/* ==========================================================================
   Study — stylesheet

   One file, no build step, no framework. Hand-edited.

   MOBILE FIRST, and not as a slogan: this app is used standing up, one-handed,
   on a phone, and read at arm's length. Every rule below is written for a
   narrow screen and widened inside min-width queries. Tap targets are 44px
   minimum, the answer field is 16px+ so iOS does not zoom the page when it is
   focused, and the two answer buttons in a session sit at the BOTTOM of the
   screen where a thumb actually reaches.

   NAMING: modifier classes for variants — `.btn--primary`, never a new rule on
   `.btn` to fix one screen. Editing a shared base class to fix a single screen
   bleeds the change across every screen using it.

   COLOUR: light pink accents on a warm cream ground, with a deep warm charcoal
   for text, plus a green and a red that appear ONLY as answer feedback. Note
   the two-pink split in the token block below — a light pink is a fill, never
   a text colour. Dark mode is a token swap at the bottom of that block;
   nothing else in the file knows which mode it is in.
   ========================================================================== */

:root {
  --bg: #fdf8f5;           /* warm cream */
  --surface: #ffffff;
  --surface-2: #fbeef1;    /* the faintest pink, for tinted panels */
  --ink: #33262d;          /* deep warm charcoal — reads with pink, not against it */
  --ink-70: #6b5a63;       /* secondary text — 6.10:1 on cream */
  --line: #f2e3e5;         /* hairlines, pink-tinted rather than grey */

  /* TWO PINKS, and the split is the whole point.
     #f4b6c2 is a FILL: lovely as a button or a progress bar, and 1.4:1 against
     cream — invisible as text. #a1485f is the same hue taken dark enough to
     read: 5.52:1 on cream, so it can carry small text and links.
     Never swap them. A light pink label on cream is unreadable. */
  --pink: #f4b6c2;         /* fills, bars, focus rings, borders */
  --pink-hover: #eda0b1;
  --pink-text: #a1485f;    /* small text, links, eyebrows */

  --good: #1c7a4a;
  --good-bg: #e6f4ec;
  --bad: #a3231c;
  --bad-bg: #fceceb;
  --radius: 14px;
  --radius-lg: 20px;
  --shadow: 0 1px 2px rgba(11, 27, 45, 0.06), 0 8px 24px rgba(11, 27, 45, 0.06);
  --gutter: 1.1rem;
  color-scheme: light dark;
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #221c20;
    --surface: #2c2429;
    --surface-2: #392e34;
    --ink: #f6eef0;
    --ink-70: #c2aeb6;
    --line: #45373d;
    --pink: #f2a7b8;
    --pink-hover: #f7bcca;
    /* On a dark ground the light pink IS legible, so text and fill converge. */
    --pink-text: #f5b8c6;
    --good: #5ed39a;
    --good-bg: #13342a;
    --bad: #ff9d99;
    --bad-bg: #3a1f22;
    --shadow: 0 1px 2px rgba(0, 0, 0, 0.4), 0 8px 24px rgba(0, 0, 0, 0.3);
  }
}

*, *::before, *::after { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font: 16px/1.55 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  -webkit-text-size-adjust: 100%;
}

h1, h2, h3 { line-height: 1.25; margin: 0 0 .5rem; }
h1 { font-size: 1.5rem; }
h2 { font-size: 1.15rem; }
p { margin: 0 0 .75rem; }
a { color: var(--pink-text); }

/* Anything focused by keyboard must be obvious — the whole app is usable from
   a laptop keyboard and that is the faster way to drill. */
:focus-visible { outline: 3px solid var(--pink); outline-offset: 2px; border-radius: 6px; }

.wrap { max-width: 46rem; margin: 0 auto; padding: 0 var(--gutter) 4rem; }
.stack > * + * { margin-top: 1rem; }
.muted { color: var(--ink-70); }
.small { font-size: .875rem; }
.center { text-align: center; }
.hidden { display: none !important; }
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* ------------------------------------------------------------------ topbar */

.topbar {
  position: sticky; top: 0; z-index: 10;
  display: flex; align-items: center; gap: .75rem;
  padding: .7rem var(--gutter);
  background: color-mix(in srgb, var(--bg) 88%, transparent);
  backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--line);
}
.topbar__title { font-size: 1rem; font-weight: 650; margin: 0; flex: 1; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.topbar__back {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 44px; min-height: 44px; margin-left: -.5rem;
  text-decoration: none; color: var(--ink); font-size: 1.25rem;
}

/* ------------------------------------------------------------------ buttons */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .5rem;
  min-height: 46px; padding: .6rem 1.1rem;
  border: 1px solid var(--line); border-radius: 999px;
  background: var(--surface); color: var(--ink);
  font: inherit; font-weight: 600; text-decoration: none;
  cursor: pointer; -webkit-tap-highlight-color: transparent;
}
.btn:hover { border-color: var(--ink-70); }
.btn:disabled { opacity: .5; cursor: not-allowed; }
/* Pink fill with DARK text, never white — white on this pink measures 1.9:1
   and is unreadable. Dark on pink measures 8.46:1. */
.btn--primary { background: var(--pink); border-color: var(--pink); color: #33262d; }
.btn--primary:hover { background: var(--pink-hover); border-color: var(--pink-hover); }
.btn--ghost { background: transparent; border-color: transparent; color: var(--ink-70); }
.btn--danger { color: var(--bad); border-color: color-mix(in srgb, var(--bad) 35%, transparent); }
.btn--block { display: flex; width: 100%; }
.btn--sm { min-height: 38px; padding: .35rem .8rem; font-size: .875rem; }

.btn-row { display: flex; flex-wrap: wrap; gap: .6rem; }

/* -------------------------------------------------------------------- cards */

.panel {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius-lg); padding: 1.1rem; box-shadow: var(--shadow);
  /* The header is sticky, so scrollIntoView would tuck a panel's own heading
     underneath it. Keep clear of it by the header's height plus a little. */
  scroll-margin-top: 4.5rem;
}

.deck-list { list-style: none; margin: 0; padding: 0; display: grid; gap: .75rem; }
.deck-item {
  display: block; padding: 1rem; scroll-margin-top: 4.5rem; text-decoration: none; color: inherit;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius); box-shadow: var(--shadow);
}
.deck-item:hover { border-color: var(--pink); }
.deck-item__name { font-weight: 650; margin: 0 0 .2rem; }
.deck-item__meta { font-size: .8125rem; color: var(--ink-70); display: flex; gap: .6rem; flex-wrap: wrap; }

.bar { height: 8px; border-radius: 999px; background: var(--surface-2); overflow: hidden; margin-top: .6rem; }
.bar__fill { height: 100%; background: var(--pink); border-radius: 999px; transition: width .3s ease; }

/* --------------------------------------------------------------------- form */

label { display: block; font-weight: 600; font-size: .9rem; margin-bottom: .3rem; }
input[type="text"], textarea, select {
  width: 100%; padding: .7rem .8rem;
  /* 16px minimum or iOS Safari zooms the page the moment this is focused. */
  font: inherit; font-size: 16px;
  color: var(--ink); background: var(--surface);
  border: 1px solid var(--line); border-radius: 12px;
}
textarea { min-height: 9rem; resize: vertical; line-height: 1.5; }
.field + .field { margin-top: .9rem; }
.hint { font-size: .8125rem; color: var(--ink-70); margin: .3rem 0 0; }

.check { display: flex; align-items: center; gap: .6rem; font-weight: 500; min-height: 40px; }
.check input { width: 20px; height: 20px; accent-color: var(--pink); flex: none; }

.notice { border-radius: 12px; padding: .7rem .9rem; font-size: .9rem; border: 1px solid; }
.notice--warn { background: var(--surface-2); border-color: var(--line); color: var(--ink); }
.notice--error { background: var(--bad-bg); border-color: color-mix(in srgb, var(--bad) 35%, transparent); color: var(--bad); }
.notice--ok { background: var(--good-bg); border-color: color-mix(in srgb, var(--good) 35%, transparent); color: var(--good); }

/* --------------------------------------------------------------- study view */

.session { display: flex; flex-direction: column; min-height: 100svh; }
.session__body { flex: 1; display: flex; flex-direction: column; justify-content: center;
  padding: 1rem var(--gutter); max-width: 46rem; margin: 0 auto; width: 100%; }
/* The action bar is pinned to the bottom on a phone: that is where the thumb
   is, and reaching to the top of a 6" screen mid-drill is a real annoyance.
   env(safe-area-inset-bottom) keeps it clear of the iPhone home indicator. */
.session__actions {
  position: sticky; bottom: 0;
  padding: .75rem var(--gutter) calc(.75rem + env(safe-area-inset-bottom, 0px));
  background: color-mix(in srgb, var(--bg) 92%, transparent);
  backdrop-filter: blur(8px);
  border-top: 1px solid var(--line);
  display: flex; gap: .6rem; width: 100%;
}
.session__actions .btn { flex: 1; }

.progress-strip { display: flex; align-items: center; gap: .6rem; padding: .5rem var(--gutter);
  font-size: .8125rem; color: var(--ink-70); }
.progress-strip .bar { flex: 1; margin: 0; }

.prompt-label {
  font-size: .75rem; text-transform: uppercase; letter-spacing: .08em;
  color: var(--pink-text); font-weight: 700; margin-bottom: .5rem;
}
.prompt {
  font-size: 1.35rem; line-height: 1.4; font-weight: 500;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius-lg); padding: 1.4rem 1.2rem; box-shadow: var(--shadow);
}
@media (min-width: 40em) { .prompt { font-size: 1.6rem; padding: 2rem 1.6rem; } }

.choices { display: grid; gap: .6rem; margin-top: 1rem; }
.choice {
  text-align: left; min-height: 54px; padding: .85rem 1rem;
  border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--surface); color: var(--ink); font: inherit; cursor: pointer;
}
.choice:hover:not(:disabled) { border-color: var(--pink); }
.choice--correct { background: var(--good-bg); border-color: var(--good); color: var(--good); font-weight: 600; }
.choice--wrong { background: var(--bad-bg); border-color: var(--bad); color: var(--bad); }
.choice:disabled { cursor: default; }

.feedback { margin-top: 1rem; border-radius: var(--radius); padding: .9rem 1rem; border: 1px solid; }
.feedback--correct { background: var(--good-bg); border-color: var(--good); }
.feedback--close { background: var(--surface-2); border-color: var(--pink); }
.feedback--wrong { background: var(--bad-bg); border-color: var(--bad); }
.feedback__head { font-weight: 700; margin-bottom: .3rem; }
.feedback__answer { font-size: 1.05rem; }

/* Spelling diff: the letters you got right, the ones you added, the ones you
   missed. Colour alone never carries it — extras are struck through and
   missing letters are underlined, so it reads without colour vision too. */
.diff { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 1.1rem; }
.diff__same { }
.diff__extra { color: var(--bad); text-decoration: line-through; }
.diff__missing { color: var(--good); text-decoration: underline; font-weight: 700; }

/* Flashcard flip. The 3D transform is skipped entirely for anyone who has
   asked for reduced motion — the card still turns over, just instantly. */
.flashcard { perspective: 1200px; margin-top: .5rem; }
.flashcard__inner {
  position: relative; transform-style: preserve-3d;
  transition: transform .45s cubic-bezier(.2,.7,.3,1);
  min-height: 15rem; cursor: pointer;
}
.flashcard--flipped .flashcard__inner { transform: rotateY(180deg); }
.flashcard__face {
  position: absolute; inset: 0; backface-visibility: hidden;
  display: flex; align-items: center; justify-content: center; text-align: center;
  padding: 1.5rem; background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius-lg); box-shadow: var(--shadow);
  font-size: 1.3rem; line-height: 1.4; overflow-y: auto;
}
.flashcard__face--back { transform: rotateY(180deg); background: var(--surface-2); }
@media (prefers-reduced-motion: reduce) {
  .flashcard__inner { transition: none; }
}

/* --------------------------------------------------------------- card table */

.card-rows { list-style: none; margin: 0; padding: 0; display: grid; gap: .5rem; }
.card-row {
  display: grid; gap: .35rem; padding: .8rem 1rem;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
}
.card-row__term { font-weight: 650; }
.card-row__def { color: var(--ink-70); font-size: .9rem; }
.card-row__foot { display: flex; align-items: center; gap: .6rem; font-size: .75rem; color: var(--ink-70); }
.pill {
  display: inline-block; padding: .1rem .55rem; border-radius: 999px;
  background: var(--surface-2); font-size: .7rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: .04em;
}
.pill--trouble { background: var(--bad-bg); color: var(--bad); }
.pill--mastered { background: var(--good-bg); color: var(--good); }

.stat-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: .6rem; }
@media (min-width: 34em) { .stat-grid { grid-template-columns: repeat(4, 1fr); } }
.stat { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); padding: .8rem; text-align: center; }
.stat__value { font-size: 1.5rem; font-weight: 700; line-height: 1.1; }
.stat__label { font-size: .75rem; color: var(--ink-70); text-transform: uppercase; letter-spacing: .05em; }

.mode-grid { display: grid; gap: .6rem; }
@media (min-width: 34em) { .mode-grid { grid-template-columns: repeat(2, 1fr); } }
.mode {
  display: block; text-align: left; text-decoration: none; color: inherit;
  padding: 1rem; background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius); box-shadow: var(--shadow);
}
.mode:hover { border-color: var(--pink); }
.mode__name { font-weight: 650; margin-bottom: .15rem; }
.mode__desc { font-size: .8125rem; color: var(--ink-70); }

.empty { text-align: center; padding: 2.5rem 1rem; color: var(--ink-70); }

/* ------------------------------------------------------- wide screens */

/* On a laptop the content sits in a 46rem column, but the header, the progress
   strip and the action bar span the window so their borders reach edge to edge.
   Without this their CONTENT stays jammed against the left edge while the
   question sits in the middle of the screen, which reads as a broken layout.
   Padding rather than max-width, so the rules still span the full width. */
@media (min-width: 50em) {
  .topbar,
  .progress-strip,
  .session__actions {
    padding-left: max(var(--gutter), calc((100% - 46rem) / 2));
    padding-right: max(var(--gutter), calc((100% - 46rem) / 2));
  }
  /* The action bar keeps its safe-area bottom padding from the rule above. */
  .session__actions .btn { max-width: 22rem; }
}

/* ------------------------------------------------------------------- sync */

/* The sync code is read off one screen and typed into another, so it gets a
   monospace face, generous letter spacing and a large size. Every ambiguous
   character is already excluded from the alphabet that generates it, but
   spacing them out is what stops a hurried reader losing their place. */
.code-display {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  /* Scales to the screen so the whole code fits on one line on a phone.
     A code split across two lines gets mis-typed. */
  font-size: clamp(.95rem, 4.1vw, 1.3rem);
  letter-spacing: .06em;
  /* Break at the dashes if it ever must wrap — break-all split groups in half,
     which is exactly where a reader loses their place. */
  word-break: normal;
  overflow-wrap: break-word;
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: .8rem 1rem;
  margin: 0;
  user-select: all;   /* one tap selects the whole code */
}


.code-input {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  letter-spacing: .05em;
  text-transform: uppercase;
}

/* A dot on the Devices button, so a sync problem is visible without opening
   the panel. Never the only signal — the panel says what happened in words. */
.sync-dot {
  display: inline-block; width: 8px; height: 8px; margin-left: .4rem;
  border-radius: 50%; background: var(--good); vertical-align: middle;
}
.sync-dot--error { background: var(--bad); }
.sync-dot--busy { background: var(--pink); }

.sync-status--error { color: var(--bad); }
.sync-status--ok { color: var(--good); }

/* -------------------------------------------------------- welcome / about */

/* A button that reads as a link. Used for "How this works" — it opens a panel
   rather than navigating, so it must not be an <a> with a fake href, and it
   must still look like the inline text link it behaves as. */
/* Inline: no min-height. Forcing a 44px box on a button that sits inside a
   sentence pushes the surrounding lines apart and makes the paragraph look
   broken. WCAG's target-size rule exempts a link inline in text for exactly
   this reason; the standalone variant below is the one that needs the box. */
.linkish {
  background: none; border: 0; padding: 0;
  font: inherit; color: var(--pink-text);
  text-decoration: underline; cursor: pointer;
}
.linkish:hover { color: var(--ink); }
.linkish--standalone { min-height: 44px; padding: 0 .5rem; }

.steps { margin: 0; padding-left: 1.25rem; }
.steps li { margin-bottom: .5rem; }
.steps li::marker { color: var(--pink-text); font-weight: 700; }

#about h3 { font-size: 1rem; margin-top: 1.1rem; }
#about h3:first-of-type { margin-top: 0; }

.footer {
  border-top: 1px solid var(--line);
  margin-top: 2rem; padding-top: .5rem; padding-bottom: 2rem;
  text-align: center;
}

/* Sits above the main content and must take NO space when empty — as a .wrap
   it kept that container's 4rem bottom padding and left a hole under the
   header on every first load. */
.install-slot { padding: 0 var(--gutter); }

.install-hint {
  display: flex; align-items: center; gap: .75rem;
  margin-top: .75rem; padding: .75rem 1rem;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius); font-size: .875rem;
}
.install-hint p { margin: 0; flex: 1; }
.install-hint button { flex: none; }


/* --------------------------------------------------- section answer review */

/* Your answer beside the right one. Two lines, aligned, so the difference is
   read at a glance — which is the whole point when the difference is a single
   accent. Not colour-only: the labels say which is which. */
.answer-compare {
  display: grid; gap: .35rem; margin: .6rem 0;
  font-size: 1.05rem;
}
.answer-compare__label {
  display: inline-block; min-width: 5.5rem;
  font-size: .75rem; text-transform: uppercase; letter-spacing: .05em;
  color: var(--ink-70); font-weight: 700;
}
.answer-compare__value { font-weight: 650; }
.answer-compare__value--typed { text-decoration: line-through; color: var(--ink-70); font-weight: 500; }
