/* ==========================================================================
   Cramlio — product (auth, dashboard, study pack)

   Layered on top of styles.css: same tokens, same paper and ink. The
   highlighter is kept for what genuinely needs attention — must-know points, a
   test that is close, the thinking loader — and nothing else. Mobile first.
   ========================================================================== */

.app{ background:var(--paper); }
.app main{ overflow-wrap:anywhere; }
.app button:disabled{ cursor:default; }
.app .btn[hidden]{ display:none; }
.app button:focus-visible, .app a:focus-visible{ outline-offset:4px; }
.app.is-working{ background:var(--ink-deep); }

.wrap--app{ max-width:760px; }

/* hidden until auth-guard.js confirms a session, so the app never flashes */
html.auth-pending body{ visibility:hidden; }

/* ---------- product nav ---------- */
.appnav .nav__inner{ gap:18px; }
.appnav .brand{ margin-right:14px; }

.appnav__tag{
  margin-right:auto; min-width:0;
  font-size:.84rem; font-weight:500; color:var(--muted-lo);
  padding-left:14px; border-left:1px solid var(--rule);
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
.appnav__exit{
  flex:none;
  display:inline-flex; align-items:center; min-height:40px;
  text-decoration:none; font-size:.92rem; font-weight:500; color:var(--muted);
  background:linear-gradient(var(--ink), var(--ink)) left calc(100% - 8px) / 0 1.5px no-repeat;
  transition:color .15s ease, background-size .2s var(--ease);
}
.appnav__exit:hover{ color:var(--ink); background-size:100% 1.5px; }
.appnav__logout{
  appearance:none; border:0; padding:0; cursor:pointer;
  font-family:var(--sans);
}
.appnav__logout[hidden]{ display:none; }
.appnav__logout:disabled{ color:var(--muted-lo); background-size:0 1.5px; }

/* the dashboard's account menu: the email in the nav, as a quiet button */
.acct{
  position:relative; margin-right:auto; min-width:0;
  padding-left:8px; border-left:1px solid var(--rule);
}
.acct__btn{
  appearance:none; background:none; border:0; cursor:pointer;
  display:flex; align-items:center; gap:4px; max-width:100%; min-height:40px;
  padding:0 6px; border-radius:8px;
  font-family:var(--sans); font-size:.84rem; font-weight:500; color:var(--muted-lo);
  transition:color .15s ease, background-color .15s ease;
}
.acct__btn:hover, .acct__btn[aria-expanded="true"]{ color:var(--ink); background:var(--paper-lo); }
.acct__btn:focus-visible{ outline:2px solid var(--ink); outline-offset:1px; }
.acct__email{ min-width:0; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.acct__chev{ flex:none; width:15px; height:15px; transition:transform .15s ease; }
.acct__btn[aria-expanded="true"] .acct__chev{ transform:rotate(180deg); }
.acct__menu{ left:8px; right:auto; min-width:190px; z-index:70; }
.acct__sep{ display:block; height:1px; margin:4px 6px; background:var(--rule-soft); }
@media (prefers-reduced-motion: reduce){ .acct__chev{ transition:none; } }

/* inside the account dialogs */
.acct__current{ font-weight:600; color:var(--ink); overflow-wrap:anywhere; }
.acct__field{ margin-top:18px; }
.acct__note{
  margin-top:12px; padding:10px 12px;
  background:var(--paper); border-radius:var(--r-sm);
  font-size:.9rem; line-height:1.5; color:var(--muted);
}
.acct__note[hidden]{ display:none; }
.acct__hint{ margin-top:8px; font-size:.86rem; color:var(--muted-lo); }
.acct__hint.is-ready{ color:#A5361F; font-weight:600; }
.confirm .input{ font-size:1rem; }

@media (max-width:560px){
  .appnav .nav__inner{ gap:14px; }
  .appnav__tag{ display:none; }
  .appnav .brand{ margin-right:auto; }
  /* on a phone the account button stays, just narrower */
  .appnav .brand:has(+ .acct){ margin-right:0; }
  .acct{ padding-left:4px; }
  .acct__email{ max-width:30vw; }
}

.app.is-working .appnav{
  background:rgba(11,18,32,.9);
  border-bottom-color:var(--ink-line);
}
.app.is-working .brand__word{ color:#F7F6F1; }
.app.is-working .brand__mark{ background:#F7F6F1; border-radius:7px; padding:3px; }
.app.is-working .appnav__tag{ color:var(--muted-dk); border-left-color:var(--ink-line-2); }
/* nothing leads out of a build in progress */
.app.is-working .appnav__exit{ display:none; }
.app.is-working .brand{ pointer-events:none; cursor:default; }

/* ---------- stage shell ---------- */
.stage{ padding:clamp(28px, 5vw, 56px) 0 clamp(44px, 7vw, 80px); }

/* the working stage sets display:flex, which would otherwise beat [hidden] */
.stage[hidden]{ display:none; }

/* moving between views: a short settle, so the change reads as a change */
.stage{ animation:stageIn .26s var(--ease) backwards; }
@keyframes stageIn{ from{ opacity:0; transform:translateY(6px); } to{ opacity:1; transform:none; } }
@media (prefers-reduced-motion: reduce){ .stage{ animation:none; } }

.stage__head{ max-width:56ch; }

/* small sentence-case label; used only where it names the thing below it */
.eyebrow{
  font-size:.84rem; font-weight:600;
  color:var(--muted-lo);
  margin-bottom:10px;
}
.eyebrow--light{ color:var(--muted-dk); }

.app-h1{
  font-family:var(--serif); font-weight:700;
  font-size:clamp(1.95rem, 6.4vw, 2.75rem);
  line-height:1.05; letter-spacing:-.033em;
  text-wrap:balance;
}
.app-h1--light{ color:#F7F6F1; }

.app-lede{
  margin-top:14px;
  font-size:clamp(1rem, 2.3vw, 1.08rem);
  color:var(--muted);
  max-width:52ch;
}

/* ==========================================================================
   ALERTS AND NOTICES
   ========================================================================== */
.alert{
  margin-top:24px;
  background:#FFF8EC;
  border:1px solid #EBCFA0;
  border-left:3px solid var(--warn);
  border-radius:var(--r-ctl);
  padding:16px 18px;
  animation:settle .22s var(--ease) backwards;
}
.alert__title{
  font-family:var(--serif); font-weight:700; font-size:1.05rem;
  letter-spacing:-.02em;
}
.alert__body{ margin-top:5px; font-size:.94rem; color:#6A4E2C; max-width:60ch; }
.alert .btn{ margin-top:14px; }

.notice{
  margin:0 0 18px;
  background:#F1FAF5;
  border:1px solid #BFE3CF;
  border-left:3px solid var(--good);
  border-radius:var(--r-ctl);
  padding:14px 16px;
  animation:settle .22s var(--ease) backwards;
}
.notice__title{ font-family:var(--serif); font-weight:700; font-size:1.02rem; letter-spacing:-.02em; }
.notice__body{ margin-top:4px; font-size:.92rem; color:#2F5A45; }
.notice[hidden], .alert[hidden]{ display:none; }

@keyframes settle{ from{ opacity:0; transform:translateY(-4px); } to{ opacity:1; transform:none; } }
@media (prefers-reduced-motion: reduce){ .alert, .notice{ animation:none; } }

/* ==========================================================================
   CONTROLS
   ========================================================================== */
.form{ margin-top:clamp(26px, 4.4vw, 38px); }

.field__label{
  display:block;
  font-size:.9rem; font-weight:600; color:var(--ink);
  margin-bottom:7px;
}

/* tertiary: small text actions */
.linkbtn{
  appearance:none; background:none; border:0; padding:4px 0; cursor:pointer;
  font-family:var(--sans); font-size:.9rem; font-weight:600; color:var(--muted);
  text-decoration:underline; text-decoration-color:var(--rule-hard);
  text-decoration-thickness:1.5px; text-underline-offset:4px;
  transition:color .15s ease, text-decoration-color .15s ease;
}
.linkbtn:hover{ color:var(--ink); text-decoration-color:var(--ink); }
.linkbtn:disabled{ color:#A8AFB8; text-decoration-color:var(--rule-soft); }
.linkbtn[hidden]{ display:none; }
.linkbtn--light{ color:var(--muted-dk); text-decoration-color:var(--ink-line-2); }
.linkbtn--light:hover{ color:#F4F5F7; text-decoration-color:#F4F5F7; }

.input, .material{
  width:100%;
  font-family:var(--sans); font-size:1rem; color:var(--ink);
  background:var(--card);
  border:1.5px solid var(--rule);
  border-radius:var(--r-ctl);
  padding:12px 14px;
  min-height:48px;
  transition:border-color .15s ease, box-shadow .15s ease;
}
.input::placeholder, .material::placeholder{ color:#8D98A3; }
.input:hover, .material:hover{ border-color:var(--rule-hard); }
.input:focus, .material:focus{
  outline:none;
  border-color:var(--ink);
  box-shadow:0 0 0 3px rgba(19,28,43,.10);
}
.input[aria-invalid="true"]{ border-color:var(--warn); }

/* iOS zooms any input under 16px on focus — keep these at 16px+ */
.material{
  display:block;
  min-height:clamp(160px, 28vh, 260px);
  resize:vertical;
  line-height:1.6;
  font-size:1rem;
}

.counter{
  flex:none;
  font-size:.8rem; font-variant-numeric:tabular-nums; color:var(--muted-lo);
}
.counter.is-over{ color:#B3543A; font-weight:600; }

/* ==========================================================================
   CREATE — three steps and one button
   ========================================================================== */
.cstep{ padding:26px 0 24px; border-top:1px solid var(--rule); }
.cstep:first-child{ border-top:0; padding-top:0; }

.cstep__h{
  display:flex; align-items:baseline; gap:12px;
  font-family:var(--serif); font-weight:700;
  font-size:clamp(1.18rem, 3.6vw, 1.32rem);
  letter-spacing:-.022em; line-height:1.25;
  color:var(--ink);
}
.cstep__n{
  flex:none;
  font-size:.95rem; font-weight:700;
  color:var(--muted-lo);
  font-variant-numeric:tabular-nums;
  min-width:.9em;
}
.cstep__sub{
  margin:6px 0 16px;
  padding-left:calc(.9em + 12px);
  font-size:.95rem; color:var(--muted); max-width:52ch;
}

/* ---------- upload ---------- */
.upload{
  position:relative;
  background:var(--card);
  border:1.5px dashed var(--rule-hard);
  border-radius:var(--r);
  transition:border-color .16s ease, background-color .16s ease, box-shadow .16s ease;
}
.upload:hover{ border-color:var(--ink); box-shadow:var(--shadow); }
.upload.is-over{ border-color:var(--marker-dk); background:#FFFDF3; border-style:solid; }

.upload__input{
  position:absolute; inset:0; width:100%; height:100%;
  opacity:0; cursor:pointer;
}
.upload__input:focus-visible + .upload__label{
  outline:2.5px solid var(--ink); outline-offset:4px; border-radius:var(--r);
}

.upload__label{
  display:flex; flex-direction:column; align-items:center; text-align:center;
  gap:6px;
  padding:clamp(26px, 6vw, 38px) 20px clamp(22px, 5vw, 30px);
  cursor:pointer;
}
.upload__icon{
  width:46px; height:46px; flex:none;
  border-radius:12px;
  background:var(--ink);
  color:#F7F6F1;
  display:grid; place-items:center;
  margin-bottom:6px;
  transition:transform .18s var(--ease);
}
.upload:hover .upload__icon{ transform:translateY(-2px); }
.upload__icon svg{ width:24px; height:24px; display:block; }

.upload__main{
  font-family:var(--serif); font-weight:700;
  font-size:clamp(1.18rem, 4.2vw, 1.4rem);
  letter-spacing:-.026em; line-height:1.15;
}
.upload__sub{ font-size:.93rem; color:var(--muted); }
.upload__kinds{ margin-top:4px; font-size:.82rem; color:var(--muted-lo); }

.upload__aside{
  margin-top:10px;
  font-size:.82rem; color:var(--muted-lo);
}

@media (prefers-reduced-motion: reduce){ .upload__icon{ transition:none; } }

/* ---------- files added so far ---------- */
.files{ display:grid; gap:8px; margin-top:12px; }
.files:empty{ display:none; }

.file{
  display:flex; align-items:center; gap:12px;
  background:var(--card);
  border:1px solid var(--rule);
  border-radius:var(--r-ctl);
  padding:10px 10px 10px 11px;
  animation:settle .22s var(--ease) backwards;
}
.file__ext{
  flex:none;
  width:38px; height:38px; border-radius:8px;
  background:var(--ink); color:#F7F6F1;
  display:grid; place-items:center;
  font-size:.6rem; font-weight:700; letter-spacing:.05em;
}
.file__body{ flex:1; min-width:0; }
.file__name{
  font-size:.93rem; font-weight:600;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
.file__meta{ font-size:.8rem; color:var(--muted-lo); margin-top:1px; }

.file--busy .file__ext{ animation:filepulse 1.3s ease-in-out infinite; }
@keyframes filepulse{ 0%,100%{ opacity:1; } 50%{ opacity:.45; } }
@media (prefers-reduced-motion: reduce){ .file--busy .file__ext{ animation:none; opacity:.6; } .file{ animation:none; } }

.file--bad{ border-color:#EBC8BC; }
.file--bad .file__ext{ background:#F2E1DB; color:#B3543A; }
.file--bad .file__meta{ color:#9C4530; }

.file__x{
  flex:none;
  width:40px; height:40px; border-radius:8px;
  border:1px solid transparent; background:none;
  color:var(--muted); cursor:pointer;
  display:grid; place-items:center;
  font-size:1.2rem; line-height:1;
  transition:border-color .15s ease, color .15s ease, background-color .15s ease;
}
.file__x:hover{ border-color:var(--rule); background:var(--paper); color:var(--ink); }

/* ---------- photos in the file list ---------- */
.file__thumb{
  flex:none; align-self:flex-start;
  width:38px; height:38px; border-radius:8px;
  object-fit:cover;
  background:var(--paper-lo);
  border:1px solid var(--rule);
}
.file--busy .file__thumb{ animation:filepulse 1.3s ease-in-out infinite; }
.file__acts{ display:flex; flex-wrap:wrap; gap:4px 16px; margin-top:2px; }
.file__acts .linkbtn{ font-size:.84rem; padding:2px 0; }
.file--editing{ align-items:flex-start; }
.file__edit{
  margin-top:10px;
  min-height:clamp(140px, 24vh, 220px);
  font-size:.95rem;
}
@media (prefers-reduced-motion: reduce){ .file--busy .file__thumb{ animation:none; opacity:.7; } }

/* while photos are being read: one quiet line with the small loader */
.files__status{
  display:flex; align-items:center; gap:10px;
  margin-top:12px;
  font-size:.9rem; font-weight:500; color:var(--muted);
}
.files__status[hidden]{ display:none; }
.cramly-loader--mini{ --uib-size:22px; padding-top:4px; flex:none; }

/* ---------- folds: the paste box and the optional name ---------- */
.fold{
  margin-top:12px;
  border:1px solid var(--rule);
  border-radius:var(--r-ctl);
  background:transparent;
  transition:background-color .16s ease;
}
.fold[open]{ background:var(--card); }

.fold__summary{
  display:flex; align-items:center; gap:10px;
  min-height:50px;
  padding:12px 16px;
  cursor:pointer;
  list-style:none;
  font-size:.95rem; font-weight:600;
  border-radius:var(--r-ctl);
}
.fold__summary:hover{ background:rgba(255,255,255,.6); }
.fold[open] .fold__summary:hover{ background:transparent; }
.fold__summary::-webkit-details-marker{ display:none; }
.fold__summary::after{
  content:""; margin-left:auto; flex:none;
  width:8px; height:8px;
  border-right:2px solid var(--muted); border-bottom:2px solid var(--muted);
  transform:rotate(45deg) translateY(-2px);
  transition:transform .2s var(--ease);
}
.fold[open] .fold__summary::after{ transform:rotate(225deg) translateY(-2px); }

.fold__tag{ font-size:.84rem; font-weight:500; color:var(--muted-lo); }
.fold__body{ padding:2px 16px 16px; }
.fold[open] .fold__body{ animation:settle .22s var(--ease) backwards; }

.fold__foot{
  display:flex; align-items:center; justify-content:flex-end;
  gap:16px; flex-wrap:wrap;
  margin-top:10px;
}

@media (prefers-reduced-motion: reduce){
  .fold__summary::after{ transition:none; }
  .fold[open] .fold__body{ animation:none; }
}

/* ---------- the two questions: snapping sliders ---------- */
.slider__top{
  display:flex; align-items:baseline; justify-content:space-between;
  gap:12px; flex-wrap:wrap;
}
.slider__value{
  flex:none;
  font-family:var(--serif); font-weight:700;
  font-size:1.2rem; letter-spacing:-.024em;
  color:var(--ink);
  font-variant-numeric:tabular-nums;
}

.slider__rail{ padding:14px 0 2px; }

.slider__input{
  -webkit-appearance:none; appearance:none;
  display:block; width:100%; height:36px; margin:0;
  background:transparent; cursor:pointer;
  touch-action:pan-y;                 /* a sideways drag moves the thumb, not the page */
  -webkit-tap-highlight-color:transparent;
  --p:.333;                           /* 0–1, set by app.js as the value changes */
}
.slider__input:focus{ outline:none; }
.slider__input:active{ cursor:grabbing; }

/* track: filled in ink up to the thumb's centre, so the chosen amount reads at a glance */
.slider__input::-webkit-slider-runnable-track{
  height:6px; border-radius:999px;
  background:linear-gradient(to right,
    var(--ink) 0, var(--ink) calc(14px + (100% - 28px) * var(--p)),
    var(--rule) calc(14px + (100% - 28px) * var(--p)), var(--rule) 100%);
}
.slider__input::-moz-range-track{
  height:6px; border-radius:999px;
  background:var(--rule);
}
.slider__input::-moz-range-progress{
  height:6px; border-radius:999px;
  background:var(--ink);
}

/* thumb — deliberately large: this gets dragged with a thumb on a phone.
   Only its size and shadow ever animate, never its position, so it can't
   trail behind the pointer while dragging. */
.slider__input::-webkit-slider-thumb{
  -webkit-appearance:none; appearance:none;
  width:28px; height:28px; border-radius:50%;
  background:var(--ink);
  border:4px solid var(--card);
  box-shadow:0 0 0 1px rgba(19,28,43,.18), 0 2px 6px rgba(19,28,43,.28), 0 0 0 0 rgba(19,28,43,0);
  margin-top:-11px;
  transition:transform .18s var(--ease), box-shadow .18s ease;
}
.slider__input::-moz-range-thumb{
  width:28px; height:28px; border-radius:50%;
  background:var(--ink);
  border:4px solid var(--card);
  box-shadow:0 0 0 1px rgba(19,28,43,.18), 0 2px 6px rgba(19,28,43,.28), 0 0 0 0 rgba(19,28,43,0);
  transition:transform .18s var(--ease), box-shadow .18s ease;
}
/* hover: a quiet halo says "this moves" */
.slider__input:hover::-webkit-slider-thumb{
  box-shadow:0 0 0 1px rgba(19,28,43,.18), 0 2px 6px rgba(19,28,43,.28), 0 0 0 6px rgba(19,28,43,.07);
}
.slider__input:hover::-moz-range-thumb{
  box-shadow:0 0 0 1px rgba(19,28,43,.18), 0 2px 6px rgba(19,28,43,.28), 0 0 0 6px rgba(19,28,43,.07);
}
/* keyboard focus: a clear ring, never only a colour */
.slider__input:focus-visible::-webkit-slider-thumb{
  box-shadow:0 0 0 1px rgba(19,28,43,.18), 0 2px 6px rgba(19,28,43,.28), 0 0 0 6px rgba(19,28,43,.18);
}
.slider__input:focus-visible::-moz-range-thumb{
  box-shadow:0 0 0 1px rgba(19,28,43,.18), 0 2px 6px rgba(19,28,43,.28), 0 0 0 6px rgba(19,28,43,.18);
}
/* dragging: the thumb lifts a little and the halo widens under the finger */
.slider__input:active::-webkit-slider-thumb{
  transform:scale(1.1);
  box-shadow:0 0 0 1px rgba(19,28,43,.18), 0 6px 14px rgba(19,28,43,.3), 0 0 0 9px rgba(19,28,43,.09);
}
.slider__input:active::-moz-range-thumb{
  transform:scale(1.1);
  box-shadow:0 0 0 1px rgba(19,28,43,.18), 0 6px 14px rgba(19,28,43,.3), 0 0 0 9px rgba(19,28,43,.09);
}

/* ticks sit under the thumb's actual travel, so the labels line up with it */
.slider__ticks{
  position:relative;
  height:32px;
  margin:0 14px;
}
.tick{
  position:absolute; top:0;
  transform:translateX(-50%);
  padding:6px 7px;
  border-radius:7px;
  font-size:.8rem; font-weight:500; font-variant-numeric:tabular-nums;
  color:var(--muted-lo);
  cursor:pointer;
  white-space:nowrap;
  transition:background-color .16s ease, color .16s ease;
}
.tick:hover{ color:var(--ink); background:var(--paper-lo); }
.tick:active{ background:var(--rule-soft); }
.tick.is-on{ color:var(--ink); font-weight:700; }

/* the chosen value settles in when it changes (app.js restarts this) */
.slider__value.is-changed{ animation:valueTick .18s var(--ease); }
@keyframes valueTick{ from{ opacity:.45; transform:translateY(2px); } to{ opacity:1; transform:none; } }
.slider__value{ display:inline-block; }

.slider__ticks .tick:nth-child(1){ left:0%; }
.slider__ticks .tick:nth-child(2){ left:16.667%; }
.slider__ticks .tick:nth-child(3){ left:33.333%; }
.slider__ticks .tick:nth-child(4){ left:50%; }
.slider__ticks .tick:nth-child(5){ left:66.667%; }
.slider__ticks .tick:nth-child(6){ left:83.333%; }
.slider__ticks .tick:nth-child(7){ left:100%; }

@media (prefers-reduced-motion: reduce){
  .tick{ transition:none; }
  .slider__input::-webkit-slider-thumb{ transition:none; }
  .slider__input::-moz-range-thumb{ transition:none; }
  .slider__input:active::-webkit-slider-thumb{ transform:none; }
  .slider__input:active::-moz-range-thumb{ transform:none; }
  .slider__value.is-changed{ animation:none; }
}

/* ---------- the action ---------- */
.actionbar{
  position:sticky; bottom:0; z-index:40;
  margin-top:12px;
  padding:16px 0 max(16px, env(safe-area-inset-bottom));
  background:linear-gradient(to bottom, rgba(244,243,237,0), var(--paper) 30%);
}
.btn--go{ width:100%; min-height:54px; padding:14px 26px; font-size:1.04rem; }
.btn--go:disabled{
  background:#D3CFC2; color:#FBFAF6;
  box-shadow:none; cursor:not-allowed;
}
.btn--go:disabled:hover{ background:#D3CFC2; }

.actionbar__msg{
  font-size:.88rem; color:#A85A17; font-weight:500;
  margin-bottom:10px;
  min-height:1.3em;
}
.actionbar__msg:empty{ display:none; }
/* a nudge, not a problem */
.actionbar__msg.is-hint{ color:var(--muted-lo); font-weight:400; }

@media (min-width:640px){
  .actionbar{ display:flex; align-items:center; gap:18px; flex-direction:row-reverse; justify-content:flex-end; }
  .btn--go{ width:auto; flex:none; }
  .actionbar__msg{ margin-bottom:0; min-height:0; text-align:left; }
}

/* ==========================================================================
   THE LOADER — one component, every AI generation

   Three cubes that hop and squash. Used wherever Cramlio is thinking: the study
   pack build, flashcards, the quiz. The animation only ever runs next to real
   status text, never alone.
   ========================================================================== */
.cramly-loader{
  --uib-size: 50px;
  --uib-color: var(--marker);
  --uib-speed: 1.75s;

  display:block;
  margin:0;
  padding-top:calc(var(--uib-size) * .34);   /* headroom, so the hop never shifts the page */
}
.cramly-loader--light{ --uib-color:var(--marker); }  /* on the dark surfaces */
.cramly-loader--ink{ --uib-color:var(--ink); }       /* on paper, where the highlighter is too faint */
.cramly-loader--center .cramly-loader__cubes{ margin-inline:auto; }

.cramly-loader__cubes{
  box-sizing:content-box;
  display:flex; align-items:flex-end; justify-content:space-between;
  padding-bottom:20%;
  width:var(--uib-size);
  height:calc(var(--uib-size) * .6);
}

.cramly-loader__cube{
  flex-shrink:0;
  display:block;
  width:calc(var(--uib-size) * .2);
  height:calc(var(--uib-size) * .2);
  animation:cramly-jump var(--uib-speed) ease-in-out infinite;
}

.cramly-loader__inner{
  display:block;
  width:100%; height:100%;
  border-radius:25%;
  background-color:var(--uib-color);
  transform-origin:center bottom;
  animation:cramly-morph var(--uib-speed) ease-in-out infinite;
}

.cramly-loader__cube:nth-child(2),
.cramly-loader__cube:nth-child(2) .cramly-loader__inner{
  animation-delay:calc(var(--uib-speed) * -.36);
}
.cramly-loader__cube:nth-child(3),
.cramly-loader__cube:nth-child(3) .cramly-loader__inner{
  animation-delay:calc(var(--uib-speed) * -.2);
}

@keyframes cramly-jump{
  0%  { transform:translateY(0px); }
  30% { transform:translateY(0px); animation-timing-function:ease-out; }
  50% { transform:translateY(-200%); animation-timing-function:ease-in; }
  75% { transform:translateY(0px); animation-timing-function:ease-in; }
}

@keyframes cramly-morph{
  0%      { transform:scaleY(1); }
  10%     { transform:scaleY(1); }
  20%,25% { transform:scaleY(.6) scaleX(1.3); animation-timing-function:ease-in-out; }
  30%     { transform:scaleY(1.15) scaleX(.9); animation-timing-function:ease-in-out; }
  40%     { transform:scaleY(1); }
  75%     { transform:scaleY(.8) scaleX(1.2); }
  70%,85%,100%{ transform:scaleY(1); }
}

/* reduced motion: still three cubes, still clearly a loading state — just still */
@media (prefers-reduced-motion: reduce){
  .cramly-loader__cube,
  .cramly-loader__inner{ animation:none; }
  .cramly-loader__inner{ opacity:.4; }
  .cramly-loader__cube:nth-child(2) .cramly-loader__inner{ opacity:.7; }
  .cramly-loader__cube:nth-child(3) .cramly-loader__inner{ opacity:1; }
}

/* ==========================================================================
   GENERATING
   ========================================================================== */
.stage--working{
  background:var(--ink-deep);
  color:#EDEFF2;
  min-height:calc(100vh - 66px);
  min-height:calc(100dvh - 66px);
  display:flex; align-items:center;
  padding-top:clamp(40px, 10vh, 90px);
  padding-bottom:clamp(40px, 10vh, 90px);
}
.working{
  width:100%; max-width:34rem;
  margin-inline:auto;
  text-align:center;
}

.steps2{
  margin:clamp(24px, 4.5vw, 32px) auto 0;
  width:100%; max-width:min(21rem, 100%);
  display:grid; gap:2px;
  text-align:left;   /* the rows read as a list; the block is what's centred */
}
.step2{
  display:flex; align-items:center; gap:14px;
  padding:13px 2px;
  border-bottom:1px solid var(--ink-line);
  color:var(--muted-dk);
  font-size:1rem;
  transition:color .25s ease;
}
.step2:last-child{ border-bottom:0; }

.step2__dot{
  flex:none;
  width:18px; height:18px; border-radius:6px;
  border:1.5px solid var(--ink-line-2);
  position:relative;
  transition:background-color .25s ease, border-color .25s ease, box-shadow .25s ease;
}

/* in progress — marked, not animated: the loader above is the motion on this screen */
.step2.is-now{ color:#F7F6F1; font-weight:600; }
.step2.is-now .step2__dot{
  border-color:var(--marker);
  background:rgba(255,224,77,.16);
  box-shadow:0 0 0 4px rgba(255,224,77,.18);
}

/* done — only ever set when the next real step has actually begun */
.step2.is-done{ color:#C7D0DA; }
.step2.is-done .step2__dot{
  border-color:var(--marker); background:var(--marker);
}
.step2.is-done .step2__dot::after{
  content:""; position:absolute; left:4px; top:7px;
  width:7px; height:3.5px;
  border-left:2px solid var(--ink-deep); border-bottom:2px solid var(--ink-deep);
  transform:rotate(-45deg);
}

.working .cramly-loader{ margin:clamp(4px, 1.6vw, 10px) 0 clamp(20px, 4vw, 28px); }

.working__note{
  margin:22px auto 0;
  font-size:.9rem; color:var(--muted-dk); max-width:42ch;
}

/* the small "making it" screens on paper (opening a pack, flashcards, quiz) */
.cardsmaking, .quizmaking{
  padding:clamp(32px, 8vw, 64px) 0;
  width:100%; max-width:34rem;
  margin-inline:auto;
  text-align:center;
}
.cardsmaking .cramly-loader, .quizmaking .cramly-loader{ margin:clamp(4px, 1.6vw, 10px) 0 clamp(18px, 3.6vw, 24px); }
.cardsmaking .app-h1, .quizmaking .app-h1{ font-size:clamp(1.6rem, 5.4vw, 2.2rem); }
.cardsmaking__note, .quizmaking__note{
  margin:14px auto 0;
  font-size:.94rem; color:var(--muted); max-width:42ch;
}

.opening__acts{
  display:flex; flex-wrap:wrap; align-items:center; gap:12px 20px;
  margin-top:14px;
}
.opening__acts .btn{ margin-top:0; }

/* ==========================================================================
   PACK NAV — one pack, four ways into it
   ========================================================================== */
.packnav{
  position:sticky; top:66px; z-index:50;   /* just under the app nav */
  background:rgba(244,243,237,.94);
  backdrop-filter:saturate(1.4) blur(10px);
  -webkit-backdrop-filter:saturate(1.4) blur(10px);
  border-bottom:1px solid var(--rule);
}
.packnav[hidden]{ display:none; }

.packnav__list{
  display:flex; gap:26px; max-width:100%;
  overflow-x:auto;
  scrollbar-width:none;
}
.packnav__list::-webkit-scrollbar{ display:none; }

.packtab{
  position:relative;
  appearance:none; background:none; border:0;
  font-family:var(--sans); font-size:.95rem; font-weight:600;
  color:var(--muted-lo);
  padding:14px 1px 13px;
  min-height:48px;
  cursor:pointer; white-space:nowrap;
  transition:color .15s ease;
}
/* the underline grows in from the middle rather than blinking on */
.packtab::after{
  content:""; position:absolute; left:0; right:0; bottom:0;
  height:2px; border-radius:2px;
  background:var(--ink);
  transform:scaleX(0);
  transition:transform .22s var(--ease);
}
.packtab:hover:not(:disabled){ color:var(--ink); }
.packtab.is-on{ color:var(--ink); }
.packtab.is-on::after{ transform:scaleX(1); }
.packtab:focus-visible{ outline-offset:-2px; }
.packtab:disabled{ color:#A8AFB8; cursor:default; }

@media (max-width:480px){
  .packnav__list{ gap:18px; }
  .packtab{ font-size:.9rem; }
}
@media (prefers-reduced-motion: reduce){ .packtab::after{ transition:none; } }

/* ==========================================================================
   STUDY GUIDE — read like a page, not a stack of cards
   ========================================================================== */
.stage--guide{ padding-top:clamp(26px, 4.4vw, 44px); }

/* ---------- header ---------- */
.gh{ padding-bottom:clamp(24px, 4vw, 32px); border-bottom:1px solid var(--rule); }

.gh__eyebrow{
  font-size:.84rem; font-weight:600;
  color:var(--muted-lo); margin-bottom:10px;
}
.gh__title{
  font-family:var(--serif); font-weight:700;
  font-size:clamp(1.9rem, 6.2vw, 2.7rem);
  line-height:1.05; letter-spacing:-.034em;
  text-wrap:balance;
}
.gh__meta{
  margin-top:8px;
  font-size:1rem; font-weight:500; color:var(--muted);
}
/* the facts of this pack, as plain text with hairline separators */
.gh__pills{
  display:flex; flex-wrap:wrap; align-items:center;
  gap:6px 0; margin-top:14px;
  font-size:.92rem; color:var(--muted);
}
.gh__pills li{ padding:0 12px; border-left:1px solid var(--rule-hard); line-height:1.3; }
.gh__pills li:first-child{ padding-left:0; border-left:0; }
.gh__pills li.is-key{ color:var(--ink); font-weight:600; }
/* a test that's today or tomorrow earns the highlighter */
.gh__pills li.is-soon span{
  background-image:linear-gradient(transparent 55%, var(--marker) 55%, var(--marker) 95%, transparent 95%);
  padding-inline:.08em;
}

.gh__read{
  margin-top:18px;
  padding-left:14px;
  border-left:2px solid var(--ink);
  font-size:.97rem; color:var(--ink); max-width:60ch;
}
.gh__src{ margin-top:14px; font-size:.82rem; color:var(--muted-lo); }

/* ---------- sections ---------- */
.gsec{ margin-top:clamp(40px, 6vw, 60px); }

.gsec__h{
  font-family:var(--serif); font-weight:700;
  font-size:clamp(1.35rem, 4vw, 1.62rem);
  letter-spacing:-.028em; line-height:1.15;
}
.gsec__sub{
  margin-top:8px;
  font-size:.95rem; color:var(--muted); max-width:56ch;
}

/* ---------- YOU MUST KNOW — the one dark panel in the guide ---------- */
.gsec--must{
  background:var(--ink-deep);
  border:1px solid rgba(255,255,255,.07);
  border-radius:var(--r);
  box-shadow:var(--shadow-lg);
  padding:clamp(22px, 4.6vw, 34px);
  color:#F4F5F7;
}
.gsec--must .gsec__h{ color:#F7F6F1; }
.gsec--must .gsec__sub{ color:var(--muted-dk); }

.must{ margin-top:22px; display:grid; gap:0; }
.must__i{
  padding:16px 0;
  border-top:1px solid var(--ink-line);
}
.must__i:first-child{ border-top:0; padding-top:0; }
.must__i:last-child{ padding-bottom:0; }

.must__stmt{
  position:relative; padding-left:20px;
  font-size:1.03rem; line-height:1.52; color:#F4F5F7; font-weight:500;
  max-width:62ch;
}
.must__stmt::before{
  content:""; position:absolute; left:0; top:.58em;
  width:8px; height:8px; border-radius:2px; background:var(--marker);
}
.must__why{
  margin-top:6px; padding-left:20px;
  font-size:.9rem; color:var(--muted-dk); max-width:62ch;
}
/* the substance behind a must-know (study guides from version 6) */
.must__detail{
  margin-top:6px; padding-left:20px;
  font-size:.94rem; line-height:1.58; color:#D5DAE1; max-width:62ch;
}

/* ---------- YOUR STUDY PLAN — a timeline, day by day ---------- */
.splan__approach{
  margin-top:14px;
  font-size:.98rem; line-height:1.6; color:var(--ink); max-width:60ch;
}

.splan{ margin-top:22px; border-top:1px solid var(--rule); }

.splan__day{
  display:grid; gap:10px;
  padding:18px 0 20px;
  border-bottom:1px solid var(--rule);
}
@media (min-width:600px){
  .splan__day{ grid-template-columns:128px minmax(0,1fr); column-gap:24px; }
  .splan__head{ grid-row:span 3; }
}

.splan__head{ display:flex; align-items:baseline; gap:10px; }
@media (min-width:600px){ .splan__head{ flex-direction:column; gap:2px; } }
.splan__n{
  font-family:var(--serif); font-weight:700;
  font-size:1.12rem; letter-spacing:-.02em;
}
.splan__mins{ font-size:.86rem; color:var(--muted-lo); font-variant-numeric:tabular-nums; }

.splan__focus{ font-size:.96rem; font-weight:600; color:var(--ink); }

.blocks{ display:grid; gap:8px; }
.block{ display:flex; align-items:baseline; gap:12px; }

.block__time{
  flex:none; width:52px;
  font-size:.82rem; font-weight:600; color:var(--muted-lo);
  font-variant-numeric:tabular-nums;
}
.block__body{ min-width:0; }
.block__do{ font-size:.95rem; line-height:1.5; }
.block__topic{ margin-top:2px; font-size:.82rem; color:var(--muted-lo); }

.splan__note{ margin-top:14px; font-size:.84rem; color:var(--muted-lo); }

/* ---------- PRIORITY TOPICS — the substantial units, so these are cards ---------- */
.topics{ margin-top:22px; display:grid; gap:14px; }

.topic{
  background:var(--card);
  border:1px solid var(--rule);
  border-radius:var(--r);
  padding:clamp(18px, 4vw, 26px);
  transition:border-color .2s ease, box-shadow .3s ease;
}

.topic__head{ display:flex; align-items:flex-start; gap:12px; }
.topic__name{
  font-family:var(--serif); font-weight:700;
  font-size:clamp(1.14rem, 3.6vw, 1.32rem);
  line-height:1.2; letter-spacing:-.026em;
  margin-top:1px;
}
.topic .rank{
  background:var(--ink); color:#F7F6F1;
  width:26px; height:26px; font-size:.82rem;
}

.topic__why{
  margin-top:10px;
  font-size:.9rem; color:var(--muted-lo); max-width:62ch;
}
.topic__exp{
  margin-top:12px;
  font-size:1rem; line-height:1.62; max-width:64ch;
}

.tblock{ margin-top:18px; padding-top:16px; border-top:1px solid var(--rule-soft); }
.tblock__h{
  font-size:.84rem; font-weight:600;
  color:var(--muted-lo);
  margin-bottom:10px;
}

.kp{ display:grid; gap:9px; }
.kp li{
  position:relative; padding-left:18px;
  font-size:.96rem; line-height:1.55; max-width:62ch;
}
.kp li::before{
  content:""; position:absolute; left:1px; top:.62em;
  width:6px; height:6px; border-radius:2px;
  background:var(--ink); opacity:.55;
}

.terms{ display:grid; gap:12px; }
.terms > div{
  display:grid; gap:2px;
  padding-left:13px; border-left:2px solid var(--rule);
}
.terms dt{ font-weight:600; font-size:.95rem; }
.terms dd{ font-size:.92rem; color:var(--muted); line-height:1.55; max-width:60ch; }

.eg{ display:grid; gap:10px; }
.eg li{
  background:var(--paper);
  border-radius:var(--r-sm);
  padding:11px 14px;
  font-size:.93rem; line-height:1.55; color:var(--ink);
}

/* ---------- the parts a topic has only when its material supports them ---------- */
.topic__sum{
  margin-top:12px;
  font-size:1.06rem; font-weight:500; line-height:1.5; color:var(--ink);
  max-width:60ch;
}
.topic__sum + .topic__why{ margin-top:6px; }

.tsteps{ display:grid; gap:8px; counter-reset:tstep; }
.tsteps li{
  position:relative; padding-left:34px;
  font-size:.96rem; line-height:1.55; max-width:62ch;
  counter-increment:tstep;
}
.tsteps li::before{
  content:counter(tstep);
  position:absolute; left:0; top:.05em;
  width:22px; height:22px; border-radius:6px;
  display:grid; place-items:center;
  border:1.5px solid var(--rule-hard);
  font-family:var(--serif); font-size:.78rem; font-weight:700; color:var(--muted);
}
/* a thread between the steps, so the order reads as a path */
.tsteps li:not(:last-child)::after{
  content:""; position:absolute; left:10.25px; top:26px; bottom:-8px;
  width:1.5px; background:var(--rule-soft);
}

.tcmp + .tcmp{ margin-top:12px; padding-top:12px; border-top:1px dashed var(--rule); }
.tcmp__pair{
  display:flex; flex-wrap:wrap; align-items:baseline; gap:2px 8px;
  font-weight:600; font-size:.96rem;
}
.tcmp__vs{ font-weight:500; font-size:.84rem; color:var(--muted-lo); }
.tcmp__diff{ margin-top:3px; font-size:.94rem; line-height:1.55; color:var(--muted); max-width:62ch; }

.tlinks{ display:grid; gap:8px; }
.tlinks li{
  position:relative; padding-left:20px;
  font-size:.95rem; line-height:1.55; max-width:62ch;
}
.tlinks li::before{
  content:""; position:absolute; left:1px; top:.72em;
  width:11px; height:1.5px; background:var(--ink); opacity:.5;
}

/* a real study warning: the one place a topic raises its voice */
.twatch{
  margin-top:18px;
  padding:13px 15px;
  background:#FFF8EC;
  border-left:3px solid var(--warn);
  border-radius:0 var(--r-sm) var(--r-sm) 0;
}
.twatch__h{ font-size:.84rem; font-weight:600; color:#8A4A12; }
.twatch__text{ margin-top:4px; font-size:.95rem; line-height:1.55; max-width:62ch; }
.twatch__text + .twatch__text{ margin-top:8px; }

.tblock > .kterm__tag--ours{ margin-bottom:10px; }
.eg--ours li{ background:transparent; border:1px dashed var(--rule-hard); }

/* ---------- a core topic's own sections: short, headed, never a wall ---------- */
.tsec{ margin-top:18px; padding-top:16px; border-top:1px solid var(--rule-soft); }
.tsec__h{
  margin:0;
  font-family:var(--serif); font-weight:700;
  font-size:1.04rem; letter-spacing:-.018em; line-height:1.3;
}
.tsec > .kterm__tag--ours{ margin-top:8px; }
.tsec__text{ margin-top:6px; font-size:.98rem; line-height:1.62; max-width:64ch; }
.tsec .kp{ margin-top:10px; }
/* Cramlio's own explanation keeps the dashed edge it has everywhere else */
.tsec--ours{
  margin-top:18px; padding:14px 16px;
  border:1px dashed var(--rule-hard); border-radius:var(--r-sm);
}
.tsec--ours .tsec__text{ color:var(--muted); }

/* "be able to": what a student can check themselves against */
.able{ display:grid; gap:8px; }
.able li{
  position:relative; padding-left:24px;
  font-size:.96rem; line-height:1.5; max-width:62ch;
}
.able li::before{
  content:""; position:absolute; left:2px; top:.28em;
  width:12px; height:12px; border-radius:3px;
  border:1.5px solid var(--rule-hard);
}

/* the source line and the way into Helper share the topic's last row */
.topic__foot{
  display:flex; flex-wrap:wrap; align-items:baseline; justify-content:space-between;
  gap:6px 16px; margin-top:16px;
}
.topic__foot .src{ margin-top:0; }
.topic__ask{ margin-left:auto; font-size:.86rem; }

/* supporting topics: lighter, rows rather than cards */
.gsec--support .topics{ gap:0; border-top:1px solid var(--rule); }
.topic--support{
  background:none; border:0; border-radius:0;
  border-bottom:1px solid var(--rule);
  padding:20px 0 18px;
}
.topic--support .topic__name{ font-size:clamp(1.06rem, 3.2vw, 1.18rem); }
.topic--support .rank{ background:transparent; color:var(--muted); border:1.5px solid var(--rule-hard); }

/* mix-ups across the whole material */
.mixlist{ margin-top:16px; display:grid; gap:10px; }
.mixlist li{
  padding:13px 15px;
  background:#FFF8EC;
  border-left:3px solid var(--warn);
  border-radius:0 var(--r-sm) var(--r-sm) 0;
  font-size:.97rem; line-height:1.55;
}
.mixlist li p{ max-width:64ch; }
.mixlist .src{ margin-top:6px; }

/* links between topics: neutral, not a warning */
.rellist{ margin-top:16px; display:grid; gap:10px; }
.rellist li{
  padding:13px 15px;
  background:var(--card);
  border:1px solid var(--rule);
  border-left:3px solid var(--ink);
  border-radius:0 var(--r-sm) var(--r-sm) 0;
  font-size:.97rem; line-height:1.55;
}
.rellist li p{ max-width:64ch; }
.rellist .src{ margin-top:6px; }

/* details worth memorizing: a compact, scannable list */
.detlist{ margin-top:14px; display:grid; gap:0; border-top:1px solid var(--rule-soft); }
.detlist li{ padding:10px 0; border-bottom:1px solid var(--rule-soft); font-size:.96rem; line-height:1.55; }
.detlist li p{ max-width:64ch; color:var(--ink); }
.detlist .src{ margin-top:4px; }

/* the last read-through */
.reviewlist{ margin-top:14px; padding-left:1.4em; display:grid; gap:8px; list-style:decimal; }
.reviewlist li{ font-size:.97rem; line-height:1.55; color:var(--ink); max-width:64ch; padding-left:4px; }
.reviewlist li::marker{ font-weight:700; color:var(--muted-lo); }

.kterm__usage{ margin-top:4px; font-size:.9rem; line-height:1.55; color:var(--muted); max-width:60ch; }
.tcmp__alike{ margin-top:3px; font-size:.9rem; line-height:1.55; color:var(--muted-lo); max-width:62ch; }

/* ---------- HOW IT FITS TOGETHER ---------- */
.big__text{
  margin-top:12px;
  font-size:1.04rem; line-height:1.65; max-width:62ch;
  padding-left:16px; border-left:2px solid var(--ink);
}
.gsec--big .src{ padding-left:18px; }

/* ---------- KEY TERMS — a glossary, set as rows ---------- */
.kterms{ margin-top:20px; border-top:1px solid var(--rule); }

.kterm{
  display:grid; gap:6px;
  padding:16px 0 17px;
  border-bottom:1px solid var(--rule);
}
@media (min-width:640px){
  .kterm{ grid-template-columns:minmax(0, 11rem) minmax(0,1fr); gap:20px; }
}
.kterm__t{ font-weight:600; font-size:1rem; letter-spacing:-.01em; }
.kterm__d{ min-width:0; }

.kterm__tag{ font-size:.8rem; font-weight:500; color:var(--muted-lo); }
/* Cramlio's own words are always marked, and marked the same way everywhere */
.kterm__tag--ours, .card__flag, .miss__flag{
  display:inline-flex; align-items:center; gap:5px;
  font-size:.78rem; font-weight:600;
  color:var(--muted);
  border:1px dashed var(--rule-hard);
  border-radius:6px; padding:1px 8px;
}
.kterm__tag--ours::before, .card__flag::before, .miss__flag::before{
  content:"+"; font-weight:700; color:var(--ink);
}
.kterm__text{ margin-top:4px; font-size:.95rem; line-height:1.58; color:var(--ink); max-width:60ch; }

/* ---------- source references ---------- */
.src{
  margin-top:14px;
  font-size:.8rem; color:var(--muted-lo);
}
.gsec--must .src{ color:#7E8C9B; padding-left:20px; margin-top:6px; }
.kp .src, .terms .src, .eg .src{ margin-top:5px; }
.kterm__d .src{ margin-top:6px; }

/* ---------- gaps + uncertainty ---------- */
.gsec--flag{
  background:var(--paper-lo);
  border-radius:var(--r);
  padding:clamp(20px, 4vw, 28px);
}
.gsec--flag .gsec__h{ font-size:clamp(1.14rem, 3.6vw, 1.3rem); }
.flaglist{ margin-top:14px; border-top:1px solid #D6D2C4; }
.flaglist li{
  padding:12px 0;
  border-bottom:1px solid #D6D2C4;
  font-size:.95rem; line-height:1.55; max-width:62ch;
}
.flaglist li:last-child{ border-bottom:0; padding-bottom:0; }
.flaglist strong{ font-weight:600; }
.flaglist p + p{ margin-top:4px; font-size:.9rem; color:var(--muted); }

/* the topic a flashcard or weak topic sent you back to */
.topic.is-pointed{
  border-color:var(--marker-dk);
  box-shadow:0 0 0 3px rgba(255,224,77,.4);
}

/* ---------- guide footer: what to do next ---------- */
.guide__actions{
  margin-top:clamp(36px, 5.4vw, 52px);
  padding-top:26px;
  border-top:1px solid var(--rule);
  display:flex; flex-direction:column; gap:10px;
}
.guide__actions .btn{ width:100%; }
.guide__more{
  display:flex; flex-wrap:wrap; gap:6px 22px;
  margin-top:16px;
}

.guide__disclaimer{
  margin-top:22px;
  font-size:.84rem; color:var(--muted-lo); max-width:58ch;
}

@media (min-width:600px){
  .guide__actions{ flex-direction:row; align-items:center; gap:12px; }
  .guide__actions .btn{ width:auto; }
}

/* ==========================================================================
   FLASHCARDS
   ========================================================================== */
.stage--cards{ padding-top:clamp(24px, 4vw, 38px); }

#cards-alert{ margin-top:18px; }

/* ---------- deck chrome ---------- */
.deck__head{
  display:flex; align-items:baseline; justify-content:space-between; gap:14px;
  margin-bottom:12px;
}
.deck__pos{
  font-size:.92rem; color:var(--muted-lo);
  font-variant-numeric:tabular-nums;
}
.deck__pos strong{ color:var(--ink); font-weight:700; font-size:1.04rem; }
.deck__mode, .quiz__mode{
  display:inline-block; margin-right:10px; vertical-align:1px;
  font-size:.76rem; font-weight:600;
  color:#F7F6F1; background:var(--ink);
  border-radius:5px; padding:2px 8px;
}
.deck__mode[hidden], .quiz__mode[hidden]{ display:none; }
.deck__progress{
  font-size:.86rem; font-weight:500;
  color:var(--muted-lo);
  text-align:right;
  font-variant-numeric:tabular-nums;
}

/* ---------- the card: one object with two sides ----------------------------
   The question is printed on the ink side, the answer is written on the paper
   side. Everything that says "same physical card" — size, radius, padding,
   shadow, the top and bottom rows — is identical on both faces.
   -------------------------------------------------------------------------- */
.card{
  display:block; width:100%;
  appearance:none; background:none; border:0; padding:0;
  font-family:var(--sans); text-align:left;
  height:clamp(300px, 50vh, 400px);   /* fixed, so nothing resizes mid-flip */
  perspective:2200px;                 /* enough depth to read as physical, not a swing */
  cursor:pointer;
  -webkit-tap-highlight-color:transparent;
  touch-action:manipulation;          /* no double-tap zoom delay on phones */
  user-select:none; -webkit-user-select:none;
}
.card:focus-visible{ outline:2.5px solid var(--ink); outline-offset:4px; border-radius:var(--r); }

/* a new card is dealt in, not swapped */
.card.is-dealt{ animation:deal .24s var(--ease) backwards; }
@keyframes deal{ from{ opacity:.35; transform:translateX(10px); } to{ opacity:1; transform:none; } }

.card__inner{
  position:relative; display:block;
  width:100%; height:100%;
  transform-style:preserve-3d;
  transition:transform .5s cubic-bezier(.22, .72, .24, 1);
}
.card.is-flipped .card__inner{ transform:rotateY(180deg); }

/* the press is on the object, not on one face */
.card:active .card__inner{ transform:scale(.992); }
.card.is-flipped:active .card__inner{ transform:rotateY(180deg) scale(.992); }

.card__face{
  position:absolute; inset:0;
  display:flex; flex-direction:column;
  padding:clamp(22px, 5.6vw, 34px);
  border-radius:var(--r);
  box-shadow:var(--shadow-lg);
  backface-visibility:hidden; -webkit-backface-visibility:hidden;
  overflow:hidden;
  transition:border-color .2s ease;
}

.card__face--front{
  background:var(--ink-deep);
  color:#F4F5F7;
  border:1px solid rgba(255,255,255,.07);
}
.card__face--back{
  background:var(--card);
  color:var(--ink);
  border:1px solid var(--rule);
  transform:rotateY(180deg);
}

.card:hover .card__face--front{ border-color:rgba(255,255,255,.18); }
.card:hover .card__face--back{ border-color:var(--rule-hard); }

/* ---------- the row that stays put across the flip ---------- */
.card__top{
  display:flex; align-items:baseline; justify-content:space-between; gap:14px;
  min-height:1.1em;
}

.card__topic{
  min-width:0;
  font-size:.84rem; font-weight:500;
  color:var(--muted-dk);
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
.card__face--back .card__topic{ color:var(--muted-lo); }
.card__topic[hidden]{ display:none; }

.card__side{
  flex:none; margin-left:auto;
  font-size:.8rem; font-weight:600;
  color:var(--muted-dk);
}
.card__side--mark{ color:var(--muted-lo); }

/* ---------- the content, optically centred ---------- */
.card__body{
  flex:1; min-height:0;
  display:grid; align-content:safe center; /* overflowing text starts within reach */
  overflow-y:auto;
  overscroll-behavior:contain;
  padding:18px 0;
}

.card__q{
  font-family:var(--serif); font-weight:700;
  font-size:clamp(1.32rem, 5vw, 1.75rem);
  line-height:1.26; letter-spacing:-.022em;
  color:#F7F6F1;
  text-wrap:balance;
}

.card__atext{
  font-size:clamp(1.04rem, 3.2vw, 1.16rem);
  line-height:1.6; color:var(--ink);
  max-width:56ch;
}

.card__hint{ font-size:.84rem; color:var(--muted-dk); }
.card__hint--back{ margin-top:10px; color:var(--muted-lo); }

/* bottom row on the paper side — same place the hint sits on the ink side */
.card__meta{ display:block; }
.card__meta:empty{ display:none; }
.card__flag[hidden]{ display:none; }

.card__src{
  display:block;
  font-size:.8rem; color:var(--muted-lo);
}
.card__src[hidden]{ display:none; }
.card__flag:not([hidden]) + .card__src{ margin-top:8px; }

/* a judged card keeps a quiet mark of what the student decided */
.card.is-got .card__face--front{ border-color:rgba(127,211,172,.4); }
.card.is-got .card__face--back{ border-color:var(--good-lo); }
.card.is-again .card__face--front{ border-color:rgba(240,168,104,.45); }
.card.is-again .card__face--back{ border-color:var(--warn-lo); }

/* switching cards must not animate the flip: the text has already changed */
.card.no-flip-anim .card__inner{ transition:none; }

/* reduced motion: the card still turns over, it just doesn't animate doing it */
@media (prefers-reduced-motion: reduce){
  .card__inner{ transition:none; }
  .card.is-dealt{ animation:none; }
  .card:active .card__inner{ transform:none; }
  .card.is-flipped:active .card__inner{ transform:rotateY(180deg); }
}

/* ---------- got it / review again ---------- */
.deck__mark{ display:flex; gap:10px; margin-top:14px; }
/* the row keeps its space while the card is face-up, so flipping never shifts
   the controls under the student's thumb */
.deck__mark[hidden]{ display:flex; visibility:hidden; pointer-events:none; }
.deck__mark:not([hidden]) .markbtn{ animation:settle .2s var(--ease) backwards; }
.deck__mark:not([hidden]) .markbtn + .markbtn{ animation-delay:.04s; }

.markbtn{
  flex:1;
  appearance:none;
  font-family:var(--sans); font-weight:600; font-size:.98rem;
  padding:12px 14px; min-height:52px;
  border-radius:var(--r-ctl);
  background:var(--card);
  border:1.5px solid var(--rule-hard);
  color:var(--ink);
  cursor:pointer;
  transition:background-color .15s ease, border-color .15s ease, color .15s ease, transform .1s ease;
}
.markbtn[hidden]{ display:none; }
.markbtn:hover{ border-color:var(--ink); }
.markbtn:active{ transform:translateY(1px); }

.markbtn--got.is-on{
  background:#E7F5ED; border-color:var(--good); color:#1C6B47;
}
.markbtn--again.is-on{
  background:#FBEFE3; border-color:var(--warn-lo); color:#8A4A12;
}

/* ---------- prev / next ---------- */
.deck__nav{
  display:flex; align-items:center; justify-content:space-between; gap:12px;
  flex-wrap:wrap;
  margin-top:16px;
}

.navbtn{
  appearance:none;
  font-family:var(--sans); font-weight:600; font-size:.94rem;
  color:var(--ink);
  background:none;
  border:1.5px solid var(--rule);
  border-radius:var(--r-ctl);
  padding:10px 18px; min-height:46px;
  cursor:pointer;
  transition:border-color .15s ease, color .15s ease, background-color .15s ease;
}
.navbtn:hover:not(:disabled){ border-color:var(--ink); background:var(--card); }
.navbtn:disabled{ color:#A8AFB8; border-color:var(--rule-soft); cursor:default; }

.deck__topiclink{ flex:none; }
.deck__topiclink[hidden]{ display:none; }

.deck__foot{
  margin-top:16px;
  font-size:.88rem; color:var(--muted-lo);
}
.deck__foot[hidden]{ display:none; }

/* "3 cards saved to review again" — also the way into reviewing them */
.deck__saved{
  appearance:none; cursor:pointer;
  display:inline-flex; align-items:center; flex-wrap:wrap; gap:4px 10px;
  max-width:100%; min-height:40px;
  margin:12px 0 0 -10px; padding:7px 10px;
  background:none; border:1px solid transparent; border-radius:var(--r-ctl);
  font-family:var(--sans); font-size:.88rem; color:var(--muted-lo); text-align:left;
  transition:background-color .15s ease, border-color .15s ease, color .15s ease, transform .12s ease;
}
.deck__saved[hidden]{ display:none; }
.deck__saved:hover{ color:var(--ink); background:var(--card); border-color:var(--rule); }
.deck__saved:active{ transform:translateY(1px); background:var(--paper-lo); }
.deck__saved:focus-visible{ outline:2px solid var(--ink); outline-offset:2px; }
.deck__savedgo{
  display:inline-flex; align-items:center; gap:2px;
  font-weight:600; color:var(--ink);
  text-decoration:underline; text-decoration-color:var(--rule-hard);
  text-decoration-thickness:1.5px; text-underline-offset:4px;
}
.deck__saved:hover .deck__savedgo{ text-decoration-color:var(--ink); }
.deck__savedgo svg{ width:14px; height:14px; }
@media (prefers-reduced-motion: reduce){ .deck__saved{ transition:none; } .deck__saved:active{ transform:none; } }

.deck__leave{ display:inline-block; margin-top:10px; margin-right:20px; }
.deck__leave[hidden]{ display:none; }

@media (min-width:600px){
  .deck__mark{ gap:12px; justify-content:flex-end; }
  .markbtn{ flex:0 1 190px; }
}

/* ---------- end of the deck: what's next ---------- */
.deckend{
  margin-top:22px;
  padding:clamp(20px, 5vw, 28px);
  background:var(--card);
  border:1px solid var(--rule);
  border-radius:var(--r);
  animation:settle .24s var(--ease) backwards;
}
.deckend[hidden]{ display:none; }
.deckend__h{
  font-family:var(--serif); font-weight:700;
  font-size:clamp(1.18rem, 4.2vw, 1.4rem);
  line-height:1.3; letter-spacing:-.02em; color:var(--ink);
}
.deckend__note{ margin-top:9px; font-size:.92rem; color:var(--muted); }
.deckend__note[hidden]{ display:none; }
.deckend__acts{
  display:flex; flex-wrap:wrap; align-items:center; gap:12px 16px;
  margin-top:18px;
}
.deckend__acts .linkbtn[hidden]{ display:none; }

/* ==========================================================================
   PRACTICE QUIZ

   The quiz borrows the deck's chrome on purpose: it is another way into one
   pack, not a different product. The answer is never shown during the run, so
   a choice is only picked or not picked.
   ========================================================================== */
.stage--quiz{ padding-top:clamp(24px, 4vw, 38px); }

#quiz-alert{ margin-top:18px; }

/* ---------- where you are ---------- */
.quiz__head{
  display:flex; align-items:baseline; justify-content:space-between; gap:14px;
  margin-bottom:12px;
}
.quiz__count{
  flex:none;
  font-size:.92rem; color:var(--muted-lo);
  font-variant-numeric:tabular-nums;
}
.quiz__count strong{ color:var(--ink); font-weight:700; font-size:1.04rem; }
.quiz__topic{
  min-width:0;
  font-size:.86rem; font-weight:500;
  color:var(--muted-lo);
  text-align:right;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
.quiz__topic[hidden]{ display:none; }

.quizbar{
  height:4px; border-radius:999px;
  background:var(--rule-soft);
  overflow:hidden;
}
.quizbar__fill{
  display:block; height:100%; width:0;
  background:var(--ink);
  border-radius:999px;
  transition:width .3s var(--ease);
}

/* ---------- the question ---------- */
.quiz__q{
  margin-top:clamp(24px, 4.6vw, 34px);
  font-family:var(--serif); font-weight:700;
  font-size:clamp(1.34rem, 5vw, 1.75rem);
  line-height:1.26; letter-spacing:-.024em;
  color:var(--ink);
  text-wrap:balance;
  max-width:36ch;
}
.quiz__q:focus{ outline:none; }

/* each new question settles in */
.quiz.is-q .quiz__q{ animation:settle .24s var(--ease) backwards; }
.quiz.is-q .choices{ animation:settle .24s var(--ease) .04s backwards; }
@media (prefers-reduced-motion: reduce){ .quiz.is-q .quiz__q, .quiz.is-q .choices{ animation:none; } }

/* ---------- the four answers ---------- */
.choices{
  margin-top:clamp(20px, 3.8vw, 26px);
  display:grid; gap:10px;
}
.choice{
  display:flex; align-items:flex-start; gap:14px;
  width:100%; text-align:left;
  appearance:none; cursor:pointer;
  font-family:var(--sans); font-size:1rem; line-height:1.45;
  color:var(--ink);
  background:var(--card);
  border:1.5px solid var(--rule);
  border-radius:var(--r-ctl);
  padding:14px 16px; min-height:56px;
  transition:border-color .14s ease, background-color .14s ease, transform .1s ease, box-shadow .14s ease;
}
.choice:hover{ border-color:var(--rule-hard); box-shadow:0 1px 0 rgba(19,28,43,.04); }
.choice:active{ transform:translateY(1px); }

.choice__key{
  flex:none;
  display:grid; place-items:center;
  width:26px; height:26px; margin-top:-1px;
  border-radius:7px;
  border:1.5px solid var(--rule);
  font-size:.8rem; font-weight:700;
  color:var(--muted);
  transition:background-color .14s ease, color .14s ease, border-color .14s ease;
}
.choice__text{ min-width:0; padding-top:1px; }

.choice.is-picked{ border-color:var(--ink); box-shadow:0 0 0 1px var(--ink); }
.choice.is-picked .choice__key{
  background:var(--ink); border-color:var(--ink); color:#F7F6F1;
}

/* ---------- keep going ---------- */
.quiz__foot{ margin-top:clamp(22px, 4vw, 28px); }
.quiz__hint{
  font-size:.88rem; color:var(--muted-lo);
  margin-bottom:12px;
}
.quiz__leave{ display:inline-block; margin-top:14px; }
.quiz__extras{ display:flex; flex-wrap:wrap; gap:0 22px; }
.quiz__leave:disabled{ cursor:default; }

/* what a new practice quiz was asked to focus on */
.quiz__focus{
  margin:-6px 0 14px;
  font-size:.86rem; color:var(--muted-lo);
  overflow-wrap:anywhere;
}
.quiz__focus[hidden]{ display:none; }

/* the "Create another practice quiz" dialog */
.newquiz{ width:min(480px, calc(100% - 32px)); }
.newquiz__field{ margin-top:18px; }
.newquiz__focus{
  display:block;
  min-height:72px; max-height:220px;
  resize:none; overflow-y:auto;
  line-height:1.55;
}
.newquiz__meta{ display:flex; align-items:flex-start; justify-content:space-between; gap:12px; margin-top:8px; }
.newquiz__hint{ font-size:.86rem; line-height:1.5; color:var(--muted); }
.newquiz__meta .counter{ flex:none; }

/* ==========================================================================
   RESULTS: what you got wrong → what it means → what to study next
   ========================================================================== */
.results[hidden]{ display:none; }
.results > *{ animation:settle .3s var(--ease) backwards; }
.results > :nth-child(2){ animation-delay:.05s; }
.results > :nth-child(3){ animation-delay:.1s; }
@media (prefers-reduced-motion: reduce){ .results > *{ animation:none; } }

.score{
  background:var(--ink-deep);
  border:1px solid rgba(255,255,255,.07);
  border-radius:var(--r);
  box-shadow:var(--shadow-lg);
  padding:clamp(24px, 5vw, 36px);
  color:#F4F5F7;
}
.score__eyebrow{
  font-size:.86rem; font-weight:600;
  color:var(--muted-dk);
}
.score__tally{
  margin-top:10px;
  font-family:var(--serif); letter-spacing:-.04em;
  line-height:1;
}
.score__got{
  font-size:clamp(3rem, 14vw, 4.2rem); font-weight:800;
  color:#FFFFFF;
}
.score__of{
  font-size:clamp(1.5rem, 6.6vw, 2rem); font-weight:600;
  color:var(--muted-dk);
}
.score__pct{
  margin-top:8px;
  font-size:.95rem; font-weight:600;
  color:#E3E7EC;
  font-variant-numeric:tabular-nums;
}
.score__h{
  margin-top:14px;
  font-family:var(--serif); font-weight:700;
  font-size:clamp(1.18rem, 4.4vw, 1.44rem);
  line-height:1.3; letter-spacing:-.02em;
  color:#F7F6F1;
  text-wrap:balance;
  max-width:32ch;
}

.rbreak{
  display:flex; flex-wrap:wrap; gap:8px 22px;
  margin-top:18px; padding-top:16px;
  border-top:1px solid var(--ink-line);
}
.rbreak__i{
  display:flex; align-items:center; gap:8px;
  font-size:.92rem;
}
.rbreak__i::before{
  content:""; width:8px; height:8px; border-radius:2px; background:var(--good-lo);
}
.rbreak__i--bad::before{ background:var(--warn-lo); }
.rbreak__n{ font-weight:700; font-variant-numeric:tabular-nums; color:#F4F5F7; }
.rbreak__l{ color:var(--muted-dk); }

.score__vs{
  margin-top:16px; padding-top:16px;
  border-top:1px solid var(--ink-line);
  font-size:.92rem; line-height:1.55; color:var(--muted-dk);
}

/* ---------- what you missed ---------- */
.missed{ margin-top:20px; display:grid; gap:12px; }
.miss{
  background:var(--card);
  border:1px solid var(--rule);
  border-left:3px solid var(--warn-lo);
  border-radius:var(--r);
  padding:clamp(18px, 4vw, 24px);
}
.miss__top:empty{ display:none; }
.miss__topic{
  font-size:.84rem; font-weight:500;
  color:var(--muted-lo);
}
.miss__q{
  margin-top:6px;
  font-family:var(--serif); font-weight:700;
  font-size:1.1rem; line-height:1.35; letter-spacing:-.015em;
  max-width:52ch;
}
.miss__rows{ margin-top:14px; display:grid; gap:6px; }
.miss__row{
  display:grid; gap:2px;
  padding:10px 13px;
  border-radius:var(--r-sm);
  background:var(--paper);
  font-size:.95rem; line-height:1.45;
}
@media (min-width:560px){
  .miss__row{ grid-template-columns:8.5rem minmax(0,1fr); gap:12px; align-items:baseline; }
}
.miss__row--right{ background:#E7F5ED; }
.miss__label{
  font-size:.82rem; font-weight:600;
  color:var(--muted-lo);
}
.miss__row--right .miss__label{ color:#1C6B47; }
.miss__val{ min-width:0; }

.miss__why{
  margin-top:14px; padding-top:14px;
  border-top:1px solid var(--rule-soft);
}
.miss__flag{ margin-bottom:8px; }
.miss__text{ font-size:.95rem; line-height:1.6; color:var(--muted); max-width:62ch; }
.miss .src{ margin-top:10px; }

/* ---------- weak topics ---------- */
.weaklist{ margin-top:20px; display:grid; gap:14px; }
.weak{
  background:var(--card);
  border:1px solid var(--rule);
  border-radius:var(--r);
  padding:clamp(20px, 4.4vw, 26px);
}
.weak__head{ display:flex; align-items:flex-start; gap:12px; }
.weak .rank{
  flex:none;
  width:26px; height:26px; margin-top:2px;
  background:var(--ink); color:#F7F6F1;
  font-size:.82rem;
}
.weak__heading{ min-width:0; }
.weak__name{
  font-family:var(--serif); font-weight:700;
  font-size:clamp(1.12rem, 4vw, 1.3rem);
  line-height:1.25; letter-spacing:-.02em;
}
.weak__score{
  margin-top:3px;
  font-size:.86rem; font-weight:600;
  color:#A85A17;
  font-variant-numeric:tabular-nums;
}
.weak__struggle{
  margin-top:14px;
  font-size:1rem; line-height:1.58; max-width:62ch;
}
.weak__matters{
  margin-top:8px;
  font-size:.93rem; line-height:1.58; color:var(--muted); max-width:62ch;
}
.weak__matters strong{ color:var(--ink); font-weight:600; }

.weak__review{
  margin-top:16px; padding:16px 18px;
  background:var(--paper);
  border-radius:var(--r-ctl);
}
.weak__reviewh{
  font-size:.84rem; font-weight:600;
  color:var(--muted-lo);
}
.weak__exp{
  margin-top:6px;
  font-size:.95rem; line-height:1.6; color:var(--ink); max-width:62ch;
}
.weak__points{ margin-top:10px; display:grid; gap:7px; }
.weak__points li{
  position:relative; padding-left:16px;
  font-size:.93rem; line-height:1.55; color:var(--muted); max-width:62ch;
}
.weak__points li::before{
  content:""; position:absolute; left:0; top:.62em;
  width:6px; height:6px; border-radius:2px; background:var(--ink); opacity:.45;
}

.weak__acts{
  display:flex; flex-wrap:wrap; align-items:center; gap:10px 20px;
  margin-top:18px;
}
.weak__acts > .linkbtn{ min-height:44px; }

/* ---------- what to do next ---------- */
.results__acts{
  margin-top:clamp(30px, 5vw, 44px);
  padding-top:clamp(22px, 4vw, 28px);
  border-top:1px solid var(--rule);
  display:grid; gap:12px; justify-items:start;
}
.results__acts .btn{ width:100%; }
.results__note{
  margin-top:-4px;
  font-size:.9rem; color:var(--muted-lo); max-width:56ch;
}

@media (min-width:600px){
  .results__acts .btn{ width:auto; }
}

/* ==========================================================================
   CRAMLIO HELPER — part of the pack, not a chat app
   ========================================================================== */
.helper__conversation{
  margin-top:24px;
  max-height:55vh; max-height:55dvh;
  overflow-y:auto; overscroll-behavior:contain;
  border-top:1px solid var(--rule);
}
.helper__empty{ color:var(--muted); padding:22px 0 10px; max-width:52ch; }
.helper__message{
  padding:18px 0;
  border-bottom:1px solid var(--rule-soft);
  animation:settle .22s var(--ease) backwards;
}
.helper__message--user{ padding-left:14px; box-shadow:inset 2px 0 0 var(--rule-hard); }
.helper__speaker{ font-size:.82rem; font-weight:600; color:var(--muted-lo); margin-bottom:5px; }
.helper__message--assistant .helper__speaker{ color:var(--ink); }
.helper__text{ white-space:pre-wrap; font-size:1rem; line-height:1.66; overflow-wrap:anywhere; max-width:64ch; }
.helper__reference{ font-size:.84rem; color:var(--muted); margin-bottom:6px; }
.helper__message.is-failed{ opacity:.7; }
.helper__message.is-failed::after{ content:'No reply yet'; display:block; font-size:.82rem; color:#A85A17; margin-top:6px; }
@media (prefers-reduced-motion: reduce){ .helper__message{ animation:none; } }

/* thinking: the status line gets three quiet dots */
.helper__status{ min-height:30px; font-size:.9rem; color:var(--muted); padding-top:8px; }
.helper__status:not(:empty)::after{
  content:""; display:inline-block; width:18px; height:6px; margin-left:8px; vertical-align:1px;
  background:
    radial-gradient(circle, var(--muted-lo) 2.2px, transparent 2.6px) 0 50% / 6px 6px no-repeat,
    radial-gradient(circle, var(--muted-lo) 2.2px, transparent 2.6px) 6px 50% / 6px 6px no-repeat,
    radial-gradient(circle, var(--muted-lo) 2.2px, transparent 2.6px) 12px 50% / 6px 6px no-repeat;
  animation:think 1.2s ease-in-out infinite;
}
@keyframes think{ 0%,100%{ opacity:.35; } 50%{ opacity:1; } }
@media (prefers-reduced-motion: reduce){ .helper__status:not(:empty)::after{ animation:none; } }

.helper__form{
  margin-top:10px;
  background:var(--card);
  border:1px solid var(--rule);
  border-radius:var(--r);
  padding:14px;
  transition:border-color .15s ease, box-shadow .15s ease;
}
.helper__form:focus-within{ border-color:var(--ink); box-shadow:0 0 0 3px rgba(19,28,43,.08); }
.helper__form .field__label{ font-size:.84rem; color:var(--muted-lo); margin-bottom:4px; }
/* no drag handle: the composer grows with what is typed (fitComposer in app.js),
   up to max-height, then scrolls inside itself */
.helper__input{
  display:block; resize:none; overflow-y:hidden;
  min-height:84px; max-height:35vh;
  line-height:1.6;
  border:0; padding:4px 0; box-shadow:none !important;
  background:transparent;
}
.helper__input:hover{ border-color:transparent; }
.helper__input[readonly]{ color:var(--muted); }
.helper__actions, .helper__context{ display:flex; align-items:center; justify-content:space-between; gap:12px; flex-wrap:wrap; }
.helper__actions{ margin-top:8px; padding-top:10px; border-top:1px solid var(--rule-soft); }
.helper__actions p{ font-size:.8rem; color:var(--muted-lo); }
.helper__actions .btn{ margin-left:auto; min-width:92px; }
.helper__context{
  margin-bottom:10px; padding:8px 10px 8px 12px;
  background:var(--paper); border-radius:var(--r-sm);
  font-size:.86rem; color:var(--muted);
}
.helper__context span{ min-width:0; flex:1 1 200px; }
.helper__context[hidden]{ display:none; }
.helper__link{ margin-top:12px; }
.weak__acts .helper__link{ margin-top:0; }
#helper-error .linkbtn{ margin-left:14px; }

@media (max-width:520px){
  .helper__actions p{ display:none; }
}

/* ---------- print: the guide is the kind of thing students print ---------- */
@media print{
  .appnav, .actionbar, .guide__actions, .guide__more, .stage--working, .packnav, .stage--cards,
  #quiz-working, #quiz-run, .results__acts, .weak__acts{ display:none !important; }
  .stage{ animation:none; }
  .app, .stage--guide{ background:#fff; }
  .gsec--must{
    background:#fff; color:var(--ink); box-shadow:none; border-color:var(--rule);
  }
  .gsec--must .gsec__h{ color:var(--ink); }
  .gsec--must .gsec__sub, .gsec--must .must__why, .gsec--must .src{ color:#555; }
  .gsec--must .must__stmt{ color:var(--ink); }
  .topic, .splan__day, .kterm, .miss, .weak{ box-shadow:none; break-inside:avoid; }
  /* the results are worth printing; the dark panel is not worth the toner */
  .score{
    background:#fff; color:var(--ink); box-shadow:none; border-color:var(--rule);
  }
  .score__eyebrow, .score__pct{ color:var(--ink); }
  .score__got, .score__h, .rbreak__n{ color:var(--ink); }
  .score__of, .rbreak__l, .score__vs{ color:#555; }
}

/* ==========================================================================
   AUTH — log in / sign up
   ========================================================================== */
.wrap--auth{ max-width:448px; }
.stage--auth{ padding-top:clamp(36px, 8vw, 80px); }

.auth__head .app-h1{ font-size:clamp(1.9rem, 6vw, 2.4rem); }
.auth__head .app-lede{ margin-top:10px; }

.auth__card{
  margin-top:clamp(24px, 4vw, 30px);
  background:var(--card);
  border:1px solid var(--rule);
  border-radius:var(--r);
  padding:clamp(20px, 5vw, 28px);
  box-shadow:var(--shadow);
}
.auth__card .alert{ margin:0 0 18px; }

.auth__field + .auth__field{ margin-top:16px; }
.auth__hint{ margin-top:6px; font-size:.84rem; color:var(--muted-lo); }
.auth__hint[hidden]{ display:none; }

.auth__submit{ width:100%; margin-top:22px; min-height:50px; }
.auth__submit:disabled{ opacity:.78; cursor:progress; }
.auth__submit[aria-busy="true"]::before{
  content:""; width:14px; height:14px; border-radius:50%;
  border:2px solid rgba(255,255,255,.35); border-top-color:#fff;
  animation:spin .7s linear infinite;
}
@keyframes spin{ to{ transform:rotate(360deg); } }
@media (prefers-reduced-motion: reduce){ .auth__submit[aria-busy="true"]::before{ animation:none; } }

.auth__switch{
  margin-top:20px; padding-top:18px;
  border-top:1px solid var(--rule-soft);
  font-size:.92rem; color:var(--muted);
  display:flex; flex-wrap:wrap; align-items:baseline; gap:2px 6px;
}
.auth__switch .linkbtn{ font-size:.92rem; color:var(--ink); }

/* ==========================================================================
   SAVE STATE — one quiet line in the app nav
   ========================================================================== */
.savestate{
  flex:none;
  display:flex; align-items:center; gap:8px;
  font-size:.84rem; font-weight:500; color:var(--muted-lo);
}
.savestate[hidden]{ display:none; }
.savestate::before{
  content:""; width:7px; height:7px; border-radius:50%;
  background:var(--good);
}
.savestate[data-state="saving"]::before{ background:var(--muted-lo); animation:think 1s ease-in-out infinite; }
.savestate[data-state="error"], .savestate[data-state="offline"],
.savestate[data-state="missing"]{ color:#8A4A12; }
.savestate[data-state="error"]::before, .savestate[data-state="offline"]::before,
.savestate[data-state="missing"]::before{ background:var(--warn); }
.savestate__retry{ font-size:.84rem; color:#8A4A12; }
.app.is-working .savestate{ display:none; }
@media (max-width:560px){
  .savestate[data-state="saving"], .savestate[data-state="saved"]{ display:none; }
}
@media (prefers-reduced-motion: reduce){ .savestate[data-state="saving"]::before{ animation:none; } }

/* ==========================================================================
   DASHBOARD — the student's home: their packs, and the way back in
   ========================================================================== */
.wrap--dash{ max-width:1000px; }

.dash__head{
  display:flex; flex-wrap:wrap; align-items:flex-end; justify-content:space-between;
  gap:20px 32px;
  padding-bottom:clamp(26px, 4vw, 36px);
  border-bottom:1px solid var(--rule);
}
.dash__head .app-lede{ margin-top:10px; }
.dash__create{ flex:none; }
@media (max-width:559px){ .dash__create{ width:100%; } }
.dash .alert{ margin-top:28px; }

.shelf__head{
  display:flex; align-items:baseline; justify-content:space-between; gap:12px;
  margin-top:clamp(28px, 4.4vw, 40px);
}
.shelf__head[hidden]{ display:none; }
.shelf__h{
  font-family:var(--serif); font-weight:700;
  font-size:1.25rem; letter-spacing:-.024em;
}
.shelf__count{ font-size:.9rem; color:var(--muted-lo); font-variant-numeric:tabular-nums; }

.spacks{
  display:grid; gap:16px;
  margin-top:16px;
}
.spacks[hidden]{ display:none; }
@media (min-width:720px){ .spacks{ grid-template-columns:repeat(2, minmax(0, 1fr)); } }

.spack{
  position:relative;
  display:flex; flex-direction:column;
  min-width:0;
  background:var(--card);
  border:1px solid var(--rule);
  border-radius:var(--r);
  padding:clamp(20px, 3.6vw, 24px);
  transition:transform .2s var(--ease), border-color .2s ease, box-shadow .2s ease;
  animation:rise .34s var(--ease) backwards;
  animation-delay:calc(var(--i, 0) * 45ms);
}
.spack:hover{ transform:translateY(-2px); border-color:var(--rule-hard); box-shadow:var(--shadow); }
.spack:focus-within{ border-color:var(--ink); }

.spack__when{
  display:flex; flex-wrap:wrap; align-items:baseline; gap:4px 12px;
  font-size:.86rem; color:var(--muted-lo);
  margin-bottom:8px;
}
.spack__test{ font-weight:600; color:var(--ink); }
.spack__test--past{ font-weight:500; color:var(--muted-lo); }
/* a test that's today or tomorrow is the one place the dashboard uses the highlighter */
.spack__test--soon{
  background-image:linear-gradient(transparent 55%, var(--marker) 55%, var(--marker) 95%, transparent 95%);
  padding-inline:.08em;
}

.spack__title{
  font-family:var(--serif); font-weight:700;
  font-size:clamp(1.3rem, 3.4vw, 1.46rem);
  line-height:1.15; letter-spacing:-.026em;
  overflow-wrap:anywhere;
  display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden;
}
.spack__subject{
  margin-top:3px;
  font-size:.92rem; color:var(--muted);
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}

/* top row: when the test is, and a quiet options button */
.spack__top{
  display:flex; align-items:flex-start; justify-content:space-between; gap:10px;
  margin:-4px -8px 4px 0;
}
.spack__top .spack__when{ margin:4px 0 0; min-height:1.3em; }
.spack__opts{ position:relative; z-index:2; flex:none; }   /* above the card-wide link */
.spack__optsbtn{
  appearance:none; background:none; border:1px solid transparent; cursor:pointer;
  width:36px; height:36px; border-radius:8px;
  display:grid; place-items:center;
  color:var(--muted-lo);
  transition:background-color .15s ease, border-color .15s ease, color .15s ease;
}
.spack__optsbtn svg{ width:18px; height:18px; fill:currentColor; }
.spack__optsbtn:hover, .spack__optsbtn[aria-expanded="true"]{
  color:var(--ink); background:var(--paper); border-color:var(--rule);
}
.spack__menu{
  position:absolute; top:calc(100% + 6px); right:0;
  min-width:196px;
  background:var(--card);
  border:1px solid var(--rule);
  border-radius:var(--r-ctl);
  box-shadow:var(--shadow-lg);
  padding:5px;
  animation:settle .16s var(--ease) backwards;
}
.spack__menu[hidden]{ display:none; }
.spack__menuitem{
  appearance:none; display:block; width:100%; text-align:left;
  background:none; border:0; cursor:pointer;
  font-family:var(--sans); font-size:.94rem; font-weight:500;
  padding:10px 12px; min-height:42px;
  border-radius:7px;
  color:var(--ink);
  white-space:nowrap;
}
.spack__menuitem:hover, .spack__menuitem:focus-visible{ background:var(--paper); }
.spack__menuitem--danger{ color:#A5361F; }
.spack__menuitem:focus-visible{ outline-offset:-2px; }

/* an open menu floats above the cards that come after it */
.spack.is-menu-open{ z-index:5; }
/* a deleted card folds away rather than vanishing */
.spack.is-leaving{
  opacity:0; transform:scale(.97);
  transition:opacity .18s ease, transform .18s ease;
  pointer-events:none;
}

/* the real numbers, as label/value rows */
.spack__stats{
  margin:18px 0 20px;
  display:grid; gap:8px;
}
.spack__stat{
  display:grid; grid-template-columns:6.5rem minmax(0,1fr); gap:12px; align-items:center;
  font-size:.92rem;
}
.spack__stat dt{ color:var(--muted-lo); }
.spack__stat dd{ display:flex; align-items:center; gap:10px; min-width:0; font-weight:600; font-variant-numeric:tabular-nums; }
.spack__stat dd > span:first-child{ min-width:4.4em; }
.spack__bar{
  flex:1; max-width:120px; height:4px; border-radius:999px;
  background:var(--rule-soft); overflow:hidden;
}
.spack__bar span{ display:block; height:100%; background:var(--ink); border-radius:999px; }
.spack__dim{ font-weight:400; color:var(--muted-lo); }
.spack__none{ margin:16px 0 20px; font-size:.92rem; color:var(--muted); }

.spack__foot{
  display:flex; align-items:center; justify-content:space-between;
  gap:16px;
  margin-top:auto; padding-top:16px;
  border-top:1px solid var(--rule-soft);
}
.spack__next{ flex:1; min-width:0; }
.spack__nexttext{ font-size:.9rem; font-weight:600; color:var(--ink); }
.spack__updated{ font-size:.82rem; color:var(--muted-lo); }
/* the whole card opens the pack; the button is where it says so */
.spack__go{ flex:none; }
.spack__go::after{ content:""; position:absolute; inset:0; border-radius:var(--r); }
.spack:hover .spack__go{ background:var(--ink-hover); }

@media (prefers-reduced-motion: reduce){
  .spack{ animation:none; transition:none; }
  .spack:hover{ transform:none; }
}

/* loading placeholders: quiet paper bars that breathe, nothing sweeping */
.spack--ghost{ gap:12px; min-height:220px; animation:ghost 1.4s ease-in-out infinite; }
.spack--ghost:hover{ transform:none; box-shadow:none; border-color:var(--rule); }
.spack--ghost span{ display:block; height:12px; border-radius:4px; background:var(--paper-lo); }
.spack--ghost span:nth-child(1){ width:34%; }
.spack--ghost span:nth-child(2){ width:72%; height:22px; }
.spack--ghost span:nth-child(3){ width:56%; margin-top:14px; }
@keyframes ghost{ 0%,100%{ opacity:1; } 50%{ opacity:.55; } }
@media (prefers-reduced-motion: reduce){ .spack--ghost{ animation:none; } }

.dash__empty{
  margin-top:clamp(28px, 4.4vw, 40px);
  display:grid; gap:24px;
  background:var(--card);
  border:1px solid var(--rule);
  border-radius:var(--r);
  padding:clamp(24px, 5.4vw, 40px);
  animation:rise .34s var(--ease) backwards;
}
.dash__empty[hidden]{ display:none; }
@media (min-width:760px){
  .dash__empty{ grid-template-columns:minmax(0,1.1fr) minmax(0,1fr); gap:48px; align-items:center; }
}
.dash__emptyTitle{
  font-family:var(--serif); font-weight:700;
  font-size:clamp(1.45rem, 4.4vw, 1.8rem); letter-spacing:-.03em;
}
.dash__emptyBody{
  margin:10px 0 22px; max-width:46ch;
  color:var(--muted);
}
.dash__steps{ border-top:1px solid var(--rule-soft); }
.dash__steps li{
  display:flex; gap:14px; align-items:baseline;
  padding:12px 0;
  border-bottom:1px solid var(--rule-soft);
  font-size:.95rem;
}
.dash__steps span{ flex:none; font-family:var(--serif); font-weight:700; color:var(--muted-lo); min-width:1em; }

/* the few remaining entrances, off when motion isn't wanted */
@media (prefers-reduced-motion: reduce){
  .dash__empty, .deckend, .deck__mark:not([hidden]) .markbtn{ animation:none; }
}

/* ---------------- Mine / Community ----------------
   The pack nav's own underline tabs, sitting on a hairline above the page. */
.dashtabs{
  display:flex; gap:26px;
  margin:-10px 0 clamp(22px, 3.6vw, 30px);
  border-bottom:1px solid var(--rule-soft);
}
.dashtab{ font-size:1rem; }
.dashpanel[hidden]{ display:none; }

/* a shared pack says so, quietly, beside its test date */
.spack__shared{ color:var(--ink); font-weight:500; }
.spack__shared::before{
  content:""; display:inline-block; vertical-align:middle;
  width:6px; height:6px; margin:-2px 6px 0 0; border-radius:50%;
  background:var(--ink); opacity:.5;
}
.spack--community .spack__title{ margin-top:2px; }
.spack__mine{ font-size:.82rem; font-weight:600; color:var(--ink); }
/* above the card-wide Study link, like the options button */
.spack__remove{ position:relative; z-index:2; font-size:.82rem; font-weight:500; }
/* a finished pack's last days, said quietly */
.spack__expires{ color:var(--muted-lo); }
.cdate__keep{ margin-top:10px; font-size:.84rem; color:var(--muted-lo); }

/* Like / Dislike: plain totals on a card, two quiet toggles inside the pack */
.spack__votes{ display:inline-flex; gap:10px; margin-left:10px; font-variant-numeric:tabular-nums; }
.spack__vote{ display:inline-flex; align-items:center; gap:4px; }
.spack__voteicon{ font-size:.86em; }
.gvotes{ display:flex; flex-wrap:wrap; align-items:center; gap:8px; margin-top:14px; }
.gvote{
  appearance:none; cursor:pointer;
  display:inline-flex; align-items:center; gap:6px;
  min-height:38px; padding:6px 12px;
  background:var(--card); color:var(--ink);
  border:1px solid var(--rule); border-radius:var(--r-ctl);
  font-family:var(--sans); font-size:.9rem; font-weight:500; font-variant-numeric:tabular-nums;
  transition:border-color .15s ease, background-color .15s ease;
}
.gvote:hover:not(:disabled){ border-color:var(--rule-hard); }
.gvote[aria-pressed="true"]{ border-color:var(--ink); background:var(--paper-lo); font-weight:600; }
.gvote:disabled{ cursor:default; opacity:.7; }
.gvote:focus-visible{ outline:2px solid var(--ink); outline-offset:2px; }
.gvote__icon{ font-size:1rem; line-height:1; }
.gvotes__note{ font-size:.84rem; color:var(--muted-lo); }
@media (prefers-reduced-motion: reduce){ .gvote{ transition:none; } }

.cfilters{ display:flex; flex-wrap:wrap; gap:10px; flex:1 1 260px; max-width:520px; justify-content:flex-end; }
.csearch{ position:relative; flex:1 1 220px; max-width:340px; }
.csubject{ flex:0 1 180px; width:auto; min-width:150px; cursor:pointer; }
@media (max-width:559px){
  .cfilters{ max-width:none; flex-basis:100%; }
  .csearch{ max-width:none; flex-basis:100%; }
  .csubject{ flex-basis:100%; }
}
.csearch__icon{
  position:absolute; left:14px; top:50%; width:18px; height:18px; margin-top:-9px;
  color:var(--muted-lo); pointer-events:none;
}
.csearch__input{ padding-left:42px; }

.dash__empty--single{ display:block; }
.cnone{
  margin-top:clamp(28px, 4.4vw, 40px);
  font-size:.95rem; color:var(--muted);
}
.cnone[hidden]{ display:none; }

/* the share dialog: what goes, what stays, and the one field */
.share .acct__field{ margin-top:18px; }
.share__checking{ margin-top:16px; font-size:.92rem; color:var(--muted-lo); }
.share__checking[hidden], .share__ready[hidden], .share__missing[hidden]{ display:none; }
.share__what{
  display:grid; gap:12px;
  margin-top:18px; padding:14px 16px;
  background:var(--paper); border-radius:var(--r-sm);
  font-size:.88rem; line-height:1.5; color:var(--muted);
}
.share__h{ font-size:.84rem; font-weight:600; color:var(--ink); margin-bottom:2px; }
.share__fine{ margin-top:12px; font-size:.84rem; line-height:1.5; color:var(--muted-lo); }
.share__missing{
  margin-top:14px; padding:14px 16px;
  background:var(--paper); border-radius:var(--r-sm);
  font-size:.92rem; line-height:1.55; color:var(--muted);
}
.confirm__acts .btn[hidden]{ display:none; }

/* ==========================================================================
   CONFIRM — a question before anything is permanently removed
   ========================================================================== */
.confirm{
  width:min(440px, calc(100% - 32px));
  margin:auto;
  padding:0;
  border:1px solid var(--rule);
  border-radius:var(--r);
  background:var(--card);
  color:var(--ink);
  box-shadow:0 30px 80px -30px rgba(11,18,32,.5);
}
.confirm::backdrop{ background:rgba(11,18,32,.42); }
.confirm[open]{ animation:settle .2s var(--ease) backwards; }
.confirm__inner{ padding:clamp(22px, 5vw, 28px); }
.confirm__h{
  font-family:var(--serif); font-weight:700;
  font-size:1.3rem; letter-spacing:-.024em; line-height:1.2;
}
.confirm__name{
  margin-top:6px;
  font-weight:600; font-size:.96rem;
  overflow-wrap:anywhere;
}
.confirm__name:empty{ display:none; }
.confirm__body{ margin-top:10px; font-size:.95rem; color:var(--muted); line-height:1.55; }
.confirm__error{
  margin-top:14px; padding:10px 12px;
  background:#FFF8EC; border-left:3px solid var(--warn); border-radius:0 var(--r-sm) var(--r-sm) 0;
  font-size:.9rem; color:#6A4E2C;
}
.confirm__error[hidden]{ display:none; }
.confirm__acts{
  display:flex; flex-wrap:wrap; justify-content:flex-end; gap:10px;
  margin-top:22px;
}
@media (max-width:420px){
  .confirm__acts{ flex-direction:column-reverse; }
  .confirm__acts .btn{ width:100%; }
}

/* ==========================================================================
   TEST DATE — a small month calendar (date-picker.js)
   Ink carries it; the highlighter only underlines the chosen day.
   ========================================================================== */
.dpick{ min-width:0; }
.dpick__panel{
  width:100%; max-width:340px;
  background:var(--card);
  border:1px solid var(--rule);
  border-radius:var(--r);
  padding:12px 12px 8px;
}
.dpick__panel[hidden]{ display:none; }
.dpick__head{
  display:flex; align-items:center; justify-content:space-between; gap:8px;
  margin-bottom:6px;
}
.dpick__month{
  font-family:var(--serif); font-weight:700;
  font-size:1rem; letter-spacing:-.018em;
  color:var(--ink);
}
.dpick__nav{
  appearance:none; background:none; cursor:pointer;
  width:36px; height:36px; border-radius:8px;
  border:1px solid transparent;
  display:grid; place-items:center;
  color:var(--ink);
  transition:background-color .15s ease, border-color .15s ease;
}
.dpick__nav svg{ width:18px; height:18px; }
.dpick__nav:hover:not(:disabled){ background:var(--paper); border-color:var(--rule); }
.dpick__nav:disabled{ color:#B9BFC6; cursor:default; }
.dpick__nav:focus-visible{ outline:2px solid var(--ink); outline-offset:1px; }

.dpick__grid{
  width:100%;
  border-collapse:separate; border-spacing:0 2px;
  table-layout:fixed;
}
.dpick__grid th{
  padding:4px 0 6px;
  font-size:.72rem; font-weight:600; letter-spacing:.02em;
  color:var(--muted-lo);
  text-align:center;
}
.dpick__grid td{ padding:0; text-align:center; }
.dpick__day{
  appearance:none; background:none; cursor:pointer;
  position:relative;
  width:100%; max-width:42px; aspect-ratio:1; min-height:34px;
  margin:0 auto;
  display:grid; place-items:center;
  border:1px solid transparent; border-radius:9px;
  font-family:var(--sans); font-size:.9rem; font-weight:500;
  font-variant-numeric:tabular-nums;
  color:var(--ink);
  transition:background-color .14s ease, border-color .14s ease, color .14s ease;
}
.dpick__day:hover:not(.is-off):not(.is-selected){ background:var(--paper); border-color:var(--rule); }
.dpick__day:focus-visible{ outline:2px solid var(--ink); outline-offset:1px; z-index:1; }
/* today: a small dot under the number, and bolder */
.dpick__day.is-today{ font-weight:700; }
.dpick__day.is-today::after{
  content:""; position:absolute; left:50%; bottom:4px;
  width:4px; height:4px; margin-left:-2px; border-radius:50%;
  background:currentColor; opacity:.55;
}
/* the chosen day: filled ink, with a thin highlighter underline */
.dpick__day.is-selected{
  background:var(--ink); border-color:var(--ink); color:#F7F6F1; font-weight:700;
  box-shadow:inset 0 -3px 0 var(--marker);
}
.dpick__day.is-selected.is-today::after{ bottom:6px; opacity:.8; }
.dpick__day.is-off{ color:#B5BBC2; cursor:default; }
.dpick__day.is-off.is-selected{ background:var(--paper-lo); border-color:var(--rule); color:var(--muted-lo); box-shadow:none; }

/* the editor's version: a field that opens the calendar beneath it */
.dpick__field{
  appearance:none; cursor:pointer;
  width:100%; min-height:48px;
  display:flex; align-items:center; justify-content:space-between; gap:12px;
  padding:10px 14px;
  background:var(--card);
  border:1.5px solid var(--rule); border-radius:var(--r-ctl);
  font-family:var(--sans); font-size:1rem; color:var(--ink); text-align:left;
  transition:border-color .15s ease, box-shadow .15s ease;
}
.dpick__field:hover{ border-color:var(--rule-hard); }
.dpick__field:focus-visible, .dpick.is-open .dpick__field{
  outline:none; border-color:var(--ink); box-shadow:0 0 0 3px rgba(19,28,43,.10);
}
.dpick__fieldtext{ display:flex; flex-wrap:wrap; align-items:baseline; gap:2px 10px; min-width:0; }
.dpick__fieldmain{ font-weight:600; }
.dpick__field.is-empty .dpick__fieldmain{ font-weight:400; color:#6E7984; }
.dpick__fieldaway{ font-size:.88rem; color:var(--muted-lo); }
.dpick__fieldicon{ flex:none; display:grid; color:var(--muted-lo); }
.dpick__fieldicon svg{ width:20px; height:20px; }
.dpick--field .dpick__panel{
  max-width:none; margin-top:8px;
  animation:settle .16s var(--ease) backwards;
}
@media (prefers-reduced-motion: reduce){
  .dpick__day, .dpick__nav{ transition:none; }
  .dpick--field .dpick__panel{ animation:none; }
}

/* the create step: the quick slider, the real day it means, and the calendar on request */
.cdate__row{
  display:flex; flex-wrap:wrap; align-items:baseline; justify-content:space-between; gap:4px 16px;
  margin-top:4px;
}
.cdate__summary{ font-size:.92rem; font-weight:500; color:var(--ink); font-variant-numeric:tabular-nums; }
.cdate__toggle{ flex:none; min-height:40px; }
.cdate__note{
  margin-top:8px; padding:10px 12px;
  background:var(--paper-lo); border-radius:var(--r-sm);
  font-size:.88rem; line-height:1.5; color:var(--muted);
  animation:settle .18s var(--ease) backwards;
}
.cdate__note[hidden], .cdate__cal[hidden]{ display:none; }
.cdate__cal{ margin-top:10px; animation:settle .18s var(--ease) backwards; }
@media (max-width:559px){
  .dpick__panel{ max-width:none; }
}
@media (prefers-reduced-motion: reduce){ .cdate__note, .cdate__cal{ animation:none; } }

/* ==========================================================================
   DASHBOARD — the date on a card, editing a pack, and the saved note
   ========================================================================== */
.spack__testwrap{ display:inline-flex; align-items:baseline; gap:6px; }
.spack__date{ font-weight:400; color:var(--muted-lo); }
.spack__date::before{ content:"·"; margin-right:6px; }
/* re-sorted after an edit: no second entrance */
.spacks.is-settled .spack{ animation:none; }

.editpack{
  width:min(540px, calc(100% - 32px));
  max-height:calc(100dvh - 48px);
  margin:max(24px, 7vh) auto auto;
  overflow:hidden;
}
.editpack[open]{ display:flex; flex-direction:column; }
.editpack__form{ display:flex; flex-direction:column; min-height:0; max-height:inherit; }
.editpack__head{
  display:flex; align-items:center; justify-content:space-between; gap:12px;
  padding:clamp(18px, 4vw, 22px) clamp(20px, 5vw, 28px) 12px;
  border-bottom:1px solid var(--rule-soft);
}
.editpack__close{
  appearance:none; background:none; cursor:pointer;
  width:40px; height:40px; margin-right:-8px; border-radius:8px;
  border:1px solid transparent;
  display:grid; place-items:center; color:var(--muted-lo);
  transition:background-color .15s ease, border-color .15s ease, color .15s ease;
}
.editpack__close svg{ width:18px; height:18px; }
.editpack__close:hover:not(:disabled){ color:var(--ink); background:var(--paper); border-color:var(--rule); }
.editpack__close:focus-visible{ outline:2px solid var(--ink); outline-offset:1px; }
.editpack__body{
  flex:1; min-height:0; overflow-y:auto; overscroll-behavior:contain;
  padding:18px clamp(20px, 5vw, 28px) 6px;
}
.editpack__field{ margin-bottom:20px; }
.editpack__field[hidden]{ display:none; }
.editpack__opt{ margin-left:6px; font-size:.8rem; font-weight:500; color:var(--muted-lo); }
.editpack__hint{ margin:-2px 0 8px; font-size:.86rem; line-height:1.5; color:var(--muted); }
.editpack__hint[hidden]{ display:none; }
#edit-date-hint{ margin:8px 0 0; }
.editpack__invalid{ margin-top:6px; font-size:.86rem; font-weight:500; color:#9A4A12; }
.editpack__invalid[hidden]{ display:none; }
.editpack__value{ font-size:1.05rem; }
.editpack .slider__top .field__label{ margin-bottom:0; }
.editpack .slider__rail{ padding-top:10px; }
.editpack__notes{
  display:block;
  min-height:84px; max-height:260px;
  resize:none; overflow-y:auto;
  line-height:1.55;
}
.editpack__count{ margin-top:6px; text-align:right; min-height:1.2em; }
.editpack .confirm__error{ margin:0 0 12px; }
.editpack__acts{
  margin:0;
  padding:14px clamp(20px, 5vw, 28px) max(16px, env(safe-area-inset-bottom));
  border-top:1px solid var(--rule-soft);
  background:var(--card);
}
.editpack__acts .btn{ min-width:120px; }

/* phones: a sheet from the bottom edge */
@media (max-width:559px){
  .editpack{
    width:100%; max-width:100%;
    max-height:calc(100dvh - 24px);
    margin:auto 0 0;
    border-radius:var(--r) var(--r) 0 0;
    border-bottom:0;
  }
  .editpack[open]{ animation:sheetUp .22s var(--ease) backwards; }
  .editpack__acts{ flex-direction:row; }
  .editpack__acts .btn{ flex:1; min-width:0; width:auto; }
}
@keyframes sheetUp{ from{ transform:translateY(24px); opacity:.6; } to{ transform:none; opacity:1; } }
@media (prefers-reduced-motion: reduce){ .editpack[open]{ animation:none; } }

.dash__toast{
  position:fixed; left:50%; bottom:max(20px, env(safe-area-inset-bottom));
  z-index:80;
  transform:translate(-50%, 12px);
  padding:10px 16px;
  border-radius:var(--r-ctl);
  background:var(--ink); color:#F7F6F1;
  font-size:.92rem; font-weight:500;
  box-shadow:var(--shadow-lg);
  opacity:0; pointer-events:none;
  transition:opacity .18s ease, transform .18s var(--ease);
}
.dash__toast:empty{ display:none; }
.dash__toast.is-on{ opacity:1; transform:translate(-50%, 0); }
.dash__toast::before{ content:"✓"; margin-right:8px; color:var(--marker); font-weight:700; }
@media (prefers-reduced-motion: reduce){ .dash__toast{ transition:none; } }

/* ==========================================================================
   SETTINGS — rows and dividers, not a card per option
   ========================================================================== */
.prefs__head{
  display:flex; flex-wrap:wrap; align-items:flex-end; justify-content:space-between; gap:12px 24px;
}
.prefs__status{
  display:flex; align-items:center; gap:8px;
  min-height:1.5em;
  font-size:.88rem; font-weight:500; color:var(--muted-lo);
}
.prefs__status:empty{ visibility:hidden; }
.prefs__status::before{
  content:""; width:7px; height:7px; border-radius:50%; background:var(--good);
}
.prefs__status[data-state="saving"]::before{ background:var(--muted-lo); animation:think 1s ease-in-out infinite; }
.prefs__status[data-state="error"]{ color:#8A4A12; }
.prefs__status[data-state="error"]::before{ background:var(--warn); }
@media (prefers-reduced-motion: reduce){ .prefs__status[data-state="saving"]::before{ animation:none; } }

.prefs__form{ margin-top:clamp(26px, 4.4vw, 38px); }
.prefs__form[aria-busy="true"]{ opacity:.7; }
.prefs__group + .prefs__group{ margin-top:clamp(34px, 5vw, 48px); }
.prefs__h{
  font-family:var(--serif); font-weight:700;
  font-size:1.25rem; letter-spacing:-.024em;
  padding-bottom:12px;
  border-bottom:1px solid var(--rule);
}

.prefrow{
  margin:0; padding:20px 0; min-width:0;
  border:0; border-bottom:1px solid var(--rule);
  display:grid; gap:12px;
}
@media (min-width:640px){
  .prefrow{ grid-template-columns:minmax(0, 1fr) minmax(0, 340px); gap:28px; align-items:center; }
}
.prefrow__label{ display:block; font-weight:600; font-size:1rem; color:var(--ink); }
.prefrow__hint{ margin-top:3px; font-size:.9rem; color:var(--muted); max-width:44ch; min-height:1.4em; }
.prefrow__control{ min-width:0; }

/* a native select dressed like the other controls */
.select{
  appearance:none; -webkit-appearance:none;
  cursor:pointer;
  padding-right:40px;
  background-image:
    linear-gradient(45deg, transparent 50%, var(--muted) 50%),
    linear-gradient(135deg, var(--muted) 50%, transparent 50%);
  background-position:calc(100% - 20px) 52%, calc(100% - 15px) 52%;
  background-size:5px 5px, 5px 5px;
  background-repeat:no-repeat;
}
.select:disabled{ cursor:default; color:var(--muted-lo); }

/* segmented choice: real radio buttons, so arrows and screen readers just work */
.seg{
  display:grid;
  background:var(--paper-lo);
  border:1px solid var(--rule);
  border-radius:var(--r-ctl);
  padding:3px; gap:3px;
}
/* equal columns, but never narrower than their own label, so none wraps */
.seg--3{ grid-template-columns:repeat(3, minmax(max-content, 1fr)); }
.seg--4{ grid-template-columns:repeat(4, minmax(0, 1fr)); }
.seg input{ position:absolute; opacity:0; width:1px; height:1px; pointer-events:none; }
.seg label{
  display:grid; place-items:center;
  min-height:40px; padding:6px 8px;
  border-radius:7px;
  font-size:.92rem; font-weight:600; color:var(--muted);
  text-align:center; line-height:1.2; white-space:nowrap;
  cursor:pointer;
  transition:background-color .15s ease, color .15s ease, box-shadow .15s ease;
}
.seg label:hover{ color:var(--ink); }
.seg input:checked + label{
  background:var(--card); color:var(--ink);
  box-shadow:0 1px 2px rgba(19,28,43,.12), 0 0 0 1px var(--rule);
}
.seg input:focus-visible + label{ outline:2.5px solid var(--ink); outline-offset:1px; }
.seg input:disabled + label{ cursor:default; opacity:.6; }
.seg__note{ margin-top:6px; font-size:.84rem; color:var(--muted-lo); }
@media (max-width:380px){ .seg label{ padding:6px 6px; } }

/* ==========================================================================
   HELPER BESIDE THE GUIDE
   A right-hand panel on wide screens, a sheet on phones. Both hold the one
   Helper body the full Helper view uses.
   ========================================================================== */
:root{ --side-w: clamp(340px, 28vw, 400px); }

.packnav__inner{ display:flex; align-items:center; gap:16px; }
.packnav__inner .packnav__list{ flex:1; min-width:0; }
.packnav__ask{
  flex:none;
  appearance:none; cursor:pointer;
  display:inline-flex; align-items:center; gap:7px;
  min-height:34px; padding:5px 12px;
  font-family:var(--sans); font-size:.88rem; font-weight:600;
  color:var(--ink); background:var(--card);
  border:1px solid var(--rule-hard); border-radius:8px;
  transition:border-color .15s ease, background-color .15s ease, color .15s ease;
}
.packnav__ask::before{
  content:""; width:7px; height:7px; border-radius:2px; background:var(--ink);
}
.packnav__ask:hover{ border-color:var(--ink); }
.packnav__ask[aria-expanded="true"]{ background:var(--ink); color:#F7F6F1; border-color:var(--ink); }
.packnav__ask[aria-expanded="true"]::before{ background:var(--marker); }
.packnav__ask[hidden]{ display:none; }

.askfab{
  position:fixed; right:16px; bottom:max(16px, env(safe-area-inset-bottom)); z-index:45;
  appearance:none; cursor:pointer;
  min-height:48px; padding:12px 18px;
  font-family:var(--sans); font-size:.95rem; font-weight:600;
  color:#F7F6F1; background:var(--ink);
  border:0; border-radius:var(--r-ctl);
  box-shadow:0 10px 26px -10px rgba(11,18,32,.55);
  animation:settle .22s var(--ease) backwards;
}
.askfab[hidden]{ display:none; }
@media (min-width:720px){ .askfab{ display:none; } }
@media (max-width:719px){ .packnav__ask{ display:none; } }
body.has-sidehelper .askfab{ display:none; }

.sidehelper{
  position:fixed; z-index:80;
  display:flex; flex-direction:column;
  background:var(--paper);
  color:var(--ink);
}
.sidehelper[hidden]{ display:none; }
.sidehelper__head{
  position:relative;
  flex:none;
  display:flex; align-items:center; justify-content:space-between; gap:12px;
  padding:12px 12px 12px 20px;
  border-bottom:1px solid var(--rule);
}
.sidehelper__title{
  font-family:var(--serif); font-weight:700;
  font-size:1.08rem; letter-spacing:-.02em;
}
.sidehelper__close{
  appearance:none; cursor:pointer;
  width:40px; height:40px; border-radius:8px;
  display:grid; place-items:center;
  background:none; border:1px solid transparent; color:var(--muted);
  transition:background-color .15s ease, border-color .15s ease, color .15s ease;
}
.sidehelper__close svg{ width:18px; height:18px; }
.sidehelper__close:hover{ color:var(--ink); background:var(--card); border-color:var(--rule); }

.sidehelper__slot{ flex:1; min-height:0; display:flex; flex-direction:column; }
/* the Helper body, laid out to fill the panel: messages scroll, composer stays */
.sidehelper .helper__body{ flex:1; min-height:0; display:flex; flex-direction:column; }
.sidehelper .helper__conversation{
  flex:1; min-height:0; max-height:none;
  margin:0; padding:0 20px;
  border-top:0;
}
.sidehelper .helper__empty{ padding-top:18px; }
.sidehelper .helper__message:last-child{ border-bottom:0; }
.sidehelper .helper__status{ flex:none; padding:4px 20px 0; min-height:26px; }
.sidehelper #helper-error{ flex:none; margin:4px 16px 0; }
.sidehelper .helper__form{
  flex:none;
  margin:8px 12px max(12px, env(safe-area-inset-bottom));
  box-shadow:0 -8px 20px -16px rgba(19,28,43,.25);
}
.sidehelper .helper__input{ min-height:52px; max-height:28vh; }
/* in the panel the title already says what this is, and the context is one line */
.sidehelper .helper__form .field__label{
  position:absolute; width:1px; height:1px; margin:-1px; overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap;
}
.sidehelper .helper__context{ flex-wrap:nowrap; gap:10px; margin-bottom:8px; padding:6px 8px 6px 12px; }
.sidehelper .helper__context span{ flex:1 1 auto; min-width:0; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.sidehelper .helper__context .linkbtn{ flex:none; font-size:.82rem; }

.sidehelper__backdrop{ position:fixed; inset:0; z-index:79; background:rgba(11,18,32,.38); }
.sidehelper__backdrop[hidden]{ display:none; }

/* wide screens: a panel beside the guide, which makes room for it */
@media (min-width:1024px){
  .sidehelper{
    top:66px; right:0; bottom:0; width:var(--side-w);
    border-left:1px solid var(--rule);
    box-shadow:-12px 0 32px -28px rgba(19,28,43,.35);
    animation:sideIn .22s var(--ease) backwards;
  }
  .sidehelper.is-closing{ animation:sideOut .18s ease forwards; }
  .sidehelper__backdrop{ display:none !important; }
  body.has-sidehelper main{ padding-right:var(--side-w); }
}
@keyframes sideIn{ from{ transform:translateX(24px); opacity:0; } to{ transform:none; opacity:1; } }
@keyframes sideOut{ to{ transform:translateX(24px); opacity:0; } }

/* phones and small tablets: a sheet over the guide, which stays where it was */
@media (max-width:1023px){
  .sidehelper{
    left:0; right:0; bottom:0;
    height:min(86vh, 720px);
    height:min(86dvh, 720px);
    border-radius:16px 16px 0 0;
    border-top:1px solid var(--rule);
    box-shadow:0 -24px 60px -24px rgba(11,18,32,.45);
    animation:sheetIn .24s var(--ease) backwards;
  }
  .sidehelper.is-closing{ animation:sheetOut .18s ease forwards; }
  .sidehelper__backdrop{ animation:fadeIn .2s ease backwards; }
  .sidehelper__head{ padding-top:16px; }
  .sidehelper__head::before{
    content:""; position:absolute; top:6px; left:50%; transform:translateX(-50%);
    width:36px; height:4px; border-radius:2px; background:var(--rule-hard);
  }
}
@keyframes sheetIn{ from{ transform:translateY(40px); opacity:0; } to{ transform:none; opacity:1; } }
@keyframes sheetOut{ to{ transform:translateY(40px); opacity:0; } }
@keyframes fadeIn{ from{ opacity:0; } to{ opacity:1; } }

@media (prefers-reduced-motion: reduce){
  .sidehelper, .sidehelper.is-closing, .sidehelper__backdrop, .askfab{ animation:none; }
}

@media print{
  .sidehelper, .sidehelper__backdrop, .askfab, .packnav__ask, .topic__ask{ display:none !important; }
  body.has-sidehelper main{ padding-right:0; }
}
