/* ------------------------------------------------------------------
   Alimiyyah Progress Tracker — emerald & gold.

   Progress is a MAGNITUDE, so it gets exactly one hue — gold — from
   empty to full. An earlier draft turned the meter green at 100%;
   that pairing failed CVD separation (gold vs green, protan ΔE 4.9)
   and over-encoded a value the "✓ Complete" badge already states in
   words. Completion is carried by the badge — icon plus label — never
   by hue alone.

   Every colour below was checked with the palette validator against
   these exact surfaces.
   ------------------------------------------------------------------ */

:root {
  color-scheme: light;

  /* parchment & ink */
  --plane:            #f6f2e6;
  --surface-1:        #fffdf7;
  --surface-2:        #f0ead8;
  --text-primary:     #10231a;
  --text-secondary:   #47584c;
  --text-muted:       #7b8a7e;
  --hairline:         #e4dbc4;
  --border:           rgba(16, 35, 26, 0.13);
  --baseline:         #c8bfa6;

  /* sequential gold — the one hue that carries magnitude */
  --gold-100:         #f4e8cb;
  --gold-200:         #e6d2a0;
  --gold-400:         #c19a3e;
  --gold-mark:        #96690c;   /* data marks: L .58, 3:1+ on surface */
  --gold-ui:          #8a5f08;   /* links, focus, emphasis */
  --gold-deep:        #6d4a05;
  --accent:           #96690c;
  /* Unfilled meter: same gold family, stepped close enough to the
     surface that an empty bar can never read as a full one. */
  --track:            #ece0c2;

  /* status — reserved, never themed */
  --status-good:      #0ca30c;
  --status-warning:   #fab219;
  --status-critical:  #d03b3b;
  --danger-bg:        #c0392b;   /* white text clears 5.9:1 */
  --correct-bg:       #15803d;   /* white text clears 5.0:1 */
  --success-text:     #0a7c0a;

  --radius:           10px;
  --shadow: 0 1px 2px rgba(16, 35, 26, .05), 0 8px 24px rgba(16, 35, 26, .07);

  /* Arabic with full harakat — the UI font drops or crowds the marks, and
     the vowels are the whole point in a morphology course. */
  --ar-face: "Geeza Pro", "Noto Naskh Arabic", "Segoe UI", Arial, sans-serif;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;
    --plane:          #0a1710;
    --surface-1:      #11241a;
    --surface-2:      #17301f;
    --text-primary:   #f4efe2;
    --text-secondary: #b6c7b8;
    --text-muted:     #86988a;
    --hairline:       #1f3a29;
    --border:         rgba(212, 180, 110, 0.15);
    --baseline:       #2c4b36;
    --gold-400:       #d9b25f;
    --gold-mark:      #b8892e;   /* L .60, 3:1+ on #11241a */
    --gold-ui:        #d9b25f;
    --gold-deep:      #8a6620;
    --accent:         #b8892e;
    --track:          #33290f;
    --status-critical: #e06a6a;
    --danger-bg:      #b3453f;   /* the dot colour is too light to carry white text */
    --correct-bg:     #17864a;   /* white text clears 4.6:1 on this surface */
    --success-text:   #35c56a;
    --shadow: 0 1px 2px rgba(0, 0, 0, .4), 0 10px 30px rgba(0, 0, 0, .45);
  }
}

:root[data-theme="dark"] {
  color-scheme: dark;
  --plane:            #0a1710;
  --surface-1:        #11241a;
  --surface-2:        #17301f;
  --text-primary:     #f4efe2;
  --text-secondary:   #b6c7b8;
  --text-muted:       #86988a;
  --hairline:         #1f3a29;
  --border:           rgba(212, 180, 110, 0.15);
  --baseline:         #2c4b36;
  --gold-400:         #d9b25f;
  --gold-mark:        #b8892e;
  --gold-ui:          #d9b25f;
  --gold-deep:        #8a6620;
  --accent:           #b8892e;
  --track:            #33290f;
  --status-critical:  #e06a6a;
  --danger-bg:        #b3453f;
  --correct-bg:       #17864a;
  --success-text:     #35c56a;
  --shadow: 0 1px 2px rgba(0, 0, 0, .4), 0 10px 30px rgba(0, 0, 0, .45);
}

* { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--plane);
  color: var(--text-primary);
  font-family: system-ui, -apple-system, "Segoe UI", sans-serif;
  font-size: 15px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

button { font: inherit; color: inherit; cursor: pointer; }
a { color: var(--gold-ui); }

/* One outer container for everything, so the left and right edges line up
   down the whole page. The dashboard is then capped from the inside — a
   centred narrow block above edge-to-edge content reads as misaligned. */
.wrap, .wrap-wide {
  max-width: 2100px;
  margin: 0 auto;
  padding: 0 40px;
}
.wrap-wide { padding-bottom: 96px; }

/* The dashboard keeps its narrow, readable measure. */
.dash { max-width: 1180px; }

/* ---------------- masthead ---------------- */

.masthead {
  border-bottom: 1px solid var(--hairline);
  background: var(--surface-1);
  position: sticky;
  top: 0;
  z-index: 40;
}
.masthead-in {
  max-width: 2100px;
  margin: 0 auto;
  padding: 14px 40px;
  display: flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
}
.brand {
  display: flex;
  align-items: center;
  gap: 11px;
  margin-right: auto;
  text-decoration: none;
  color: inherit;
}
/* The artwork carries its own dark-green ground, so it sits as a badge in
   both themes rather than needing a transparent cutout. */
.brand-mark {
  width: 34px;
  height: 34px;
  border-radius: 8px;
  flex: none;
  display: block;
  border: 1px solid var(--border);
}
.brand h1 { font-size: 17px; font-weight: 600; margin: 0; letter-spacing: -0.01em; }
.brand:hover h1 { color: var(--gold-ui); }
.brand .ar { font-size: 15px; color: var(--text-muted); }

.toolbar { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }

.btn {
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 7px 12px;
  font-size: 13px;
  color: var(--text-secondary);
  transition: background .12s, color .12s, border-color .12s;
  white-space: nowrap;
}
.btn:hover { background: var(--surface-2); color: var(--text-primary); }
.btn.primary { background: var(--accent); border-color: var(--accent); color: #fff; }
.btn.primary:hover { background: var(--gold-deep); border-color: var(--gold-deep); }
.btn.sm { padding: 4px 9px; font-size: 12px; }
.btn.ghost { background: transparent; border-color: transparent; }
.btn.ghost:hover { background: var(--surface-2); }

.search {
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 7px 11px;
  font-size: 13px;
  color: var(--text-primary);
  width: 210px;
  min-width: 140px;
}
.search:focus { outline: 2px solid var(--accent); outline-offset: -1px; }
.search::placeholder { color: var(--text-muted); }

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

.sync {
  font-size: 12px;
  color: var(--text-muted);
  display: inline-flex;
  align-items: center;
  gap: 6px;
  white-space: nowrap;
  padding-right: 4px;
}
.sync::before {
  content: "";
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--text-muted);
  flex: none;
}
.sync.ok::before      { background: var(--status-good); }
.sync.syncing::before { background: var(--accent); }
.sync.warn::before    { background: var(--status-warning); }
.sync.warn            { color: var(--text-secondary); }
.sync.bad::before     { background: var(--status-critical); }
.sync.bad             { color: var(--status-critical); }

/* ---------------- dashboard ---------------- */

.dash {
  display: grid;
  grid-template-columns: minmax(260px, 320px) 1fr;
  gap: 20px;
  margin: 28px 0 12px;
  align-items: start;
}
@media (max-width: 860px) { .dash { grid-template-columns: 1fr; } }
/* min-width:0 everywhere on this chain: grid/flex items default to min-content
   sizing, which lets the chart's min-width bleed out and widen the column. */
.dash > * { min-width: 0; }
.dash-left, .dash-right {
  display: flex; flex-direction: column; gap: 12px; min-width: 0;
}
.dash-left .focus { flex: 1; }
.tiles, .panel, .chart { min-width: 0; }

.card {
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}


.tiles {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 12px;
}
.tile { padding: 14px 16px; }
.tile .t-label {
  font-size: 12px;
  color: var(--text-muted);
  margin-bottom: 4px;
}
.tile .t-value { font-size: 26px; font-weight: 600; letter-spacing: -0.02em; line-height: 1.15; }
.tile .t-foot { font-size: 12px; color: var(--text-secondary); margin-top: 2px; }

.panel { padding: 16px 18px; margin-top: 12px; }
.panel h2 {
  font-size: 13px;
  font-weight: 600;
  margin: 0 0 2px;
  letter-spacing: -0.005em;
}
.panel .sub { font-size: 12px; color: var(--text-muted); margin: 0 0 14px; }

/* charts */
.bar-track { fill: var(--track); }
.ax-label { font-size: 11px; fill: var(--text-muted); }
.ax-value { font-size: 11px; fill: var(--text-secondary); font-variant-numeric: tabular-nums; }
.gridline { stroke: var(--hairline); stroke-width: 1; }

.hit { fill: transparent; cursor: pointer; }

.tooltip {
  position: fixed;
  z-index: 90;
  pointer-events: none;
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: 8px;
  box-shadow: var(--shadow);
  padding: 8px 11px;
  font-size: 12px;
  color: var(--text-primary);
  max-width: 240px;
  opacity: 0;
  transition: opacity .1s;
}
.tooltip.on { opacity: 1; }
.tooltip .tt-title { font-weight: 600; margin-bottom: 2px; }
.tooltip .tt-row { color: var(--text-secondary); }
.tooltip .tt-key {
  display: inline-block;
  width: 8px; height: 8px;
  border-radius: 2px;
  background: var(--accent);
  margin-right: 6px;
}

/* focus card */
.focus { padding: 16px 18px; margin-top: 12px; }
.focus .f-label {
  font-size: 12px; color: var(--text-muted);
  text-transform: uppercase; letter-spacing: .07em; margin-bottom: 8px;
}
.focus .f-unit { font-size: 15px; font-weight: 600; margin-bottom: 2px; }
.focus .f-where { font-size: 12px; color: var(--text-secondary); }
.focus .f-actions { margin-top: 12px; display: flex; gap: 8px; flex-wrap: wrap; }

/* ---------------- years & subjects ---------------- */

.section-head {
  display: flex; align-items: baseline; gap: 12px;
  margin: 36px 0 14px;
  flex-wrap: wrap;
}
.section-head h2 { font-size: 15px; font-weight: 600; margin: 0; }
.section-head .hint { font-size: 12px; color: var(--text-muted); margin-left: auto; }

.year { margin-bottom: 14px; }

.year-head {
  display: flex; align-items: center; gap: 14px;
  padding: 14px 18px;
  cursor: pointer;
  user-select: none;
  border-radius: var(--radius);
}
.year-head:hover { background: var(--surface-2); }
.year-head .chev {
  color: var(--text-muted);
  transition: transform .15s;
  flex: none;
  display: inline-flex;
}
.year.open .year-head .chev { transform: rotate(90deg); }
.year-titles { min-width: 0; flex: 1; }
.year-titles h3 { margin: 0; font-size: 16px; font-weight: 600; letter-spacing: -0.01em; }
.year-titles p { margin: 1px 0 0; font-size: 12px; color: var(--text-muted); }
.year-stat {
  display: flex; align-items: center; gap: 12px;
  flex: none;
}
.year-pct {
  font-size: 13px; font-weight: 600;
  font-variant-numeric: tabular-nums;
  min-width: 42px; text-align: right;
}
.year-count { font-size: 12px; color: var(--text-muted); font-variant-numeric: tabular-nums; }

.meter {
  height: 8px;
  background: var(--track);
  border-radius: 4px;
  overflow: hidden;
  width: 140px;
  flex: none;
}
.meter .fill {
  height: 100%;
  background: var(--accent);
  border-radius: 0 4px 4px 0;
  transition: width .4s cubic-bezier(.4,0,.2,1);
}
/* A full meter stays gold. Completion is stated by the "Complete"
   badge (tick + word), never by a hue change alone. */
.meter .fill[data-full="1"] { border-radius: 4px; }
.meter.slim { height: 6px; width: 100%; border-radius: 3px; }
.meter.slim .fill { border-radius: 0 3px 3px 0; }

.year-body { display: none; padding: 4px 0 10px; }
.year.open .year-body { display: block; }

.subjects { display: grid; gap: 10px; }

.subject { overflow: hidden; }

.subj-head {
  display: flex; align-items: center; gap: 14px;
  padding: 13px 16px;
  cursor: pointer;
  user-select: none;
}
.subj-head:hover { background: var(--surface-2); }
.subj-head .chev { color: var(--text-muted); transition: transform .15s; flex: none; display: inline-flex; }
.subject.open .subj-head .chev { transform: rotate(90deg); }
.subj-titles { min-width: 0; flex: 1; }
.subj-titles h4 {
  margin: 0; font-size: 14px; font-weight: 600;
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
}
.subj-titles .ar { color: var(--text-muted); font-weight: 400; font-size: 13px; }
.subj-titles p {
  margin: 2px 0 0; font-size: 12px; color: var(--text-secondary);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* When open, the full outline shows in the body — don't repeat it in the header. */
.subject.open .subj-titles p { display: none; }

.badge {
  font-size: 11px;
  padding: 2px 7px;
  border-radius: 20px;
  border: 1px solid var(--border);
  color: var(--text-secondary);
  white-space: nowrap;
  display: inline-flex; align-items: center; gap: 4px;
}
.badge.done { color: var(--success-text); border-color: var(--status-good); }
.badge.done svg { flex: none; }

.subj-stat { display: flex; align-items: center; gap: 12px; flex: none; }
.subj-count {
  font-size: 12px; color: var(--text-muted);
  font-variant-numeric: tabular-nums; min-width: 46px; text-align: right;
}

.subj-body { display: none; border-top: 1px solid var(--hairline); }
.subject.open .subj-body { display: block; }

.subj-outline {
  padding: 14px 20px 4px;
  font-size: 13px;
  color: var(--text-secondary);
  max-width: 78ch;
}

/* ==================================================================
   Pace against the academic year

   Day-type colours follow the institute's own printed key so the chart
   reads the same way the calendar does. Validated against both chart
   surfaces: worst adjacent separation ΔE 20.7 light, 19.0 dark.
   ================================================================== */

.pacing {
  --k-class:    #cdbf98;
  --k-holiday:  #5c9a3a;
  --k-revision: #2f7fb5;
  --k-exam:     #a8830e;
  margin-bottom: 18px;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .pacing {
    --k-class:    #3a5a45;
    --k-holiday:  #5f9b46;
    --k-revision: #4a90c8;
    --k-exam:     #b08a2a;
  }
}
:root[data-theme="dark"] .pacing {
  --k-class:    #3a5a45;
  --k-holiday:  #5f9b46;
  --k-revision: #4a90c8;
  --k-exam:     #b08a2a;
}

.pace-head {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 18px; flex-wrap: wrap;
  margin-bottom: 6px;
}
.pace-head h2 { margin: 0; }
.pace-head .sub { max-width: 62ch; }

.yr-tabs { display: flex; gap: 6px; flex-wrap: wrap; flex: none; }
.yr-tab {
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: 20px;
  padding: 5px 12px;
  font-size: 12.5px;
  color: var(--text-secondary);
  white-space: nowrap;
}
.yr-tab:hover { border-color: var(--gold-ui); color: var(--text-primary); }
.yr-tab.on { background: var(--accent); border-color: var(--accent); color: #fff; }
.yr-tab:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.pace-chart { margin: 10px 0 4px; max-width: 1500px; }
.pace-chart .gridline { stroke: var(--hairline); stroke-width: 1; }
.pace-chart .ax-value, .pace-chart .ax-label, .pace-chart .ax-pct {
  font-size: 10.5px; fill: var(--text-muted); font-variant-numeric: tabular-nums;
}
.pace-chart .ax-pct { font-size: 9.5px; }

/* The ghost — the rate that finishes the year on time. */
.pace-target {
  fill: none;
  stroke: var(--baseline);
  stroke-width: 2;
  stroke-dasharray: 6 4;
}
.pace-mine {
  fill: none;
  stroke: var(--accent);
  stroke-width: 2.5;
  stroke-linejoin: round;
  stroke-linecap: round;
}
.pace-dot { fill: var(--accent); stroke: var(--surface-1); stroke-width: 2; }

.pace-today { stroke: var(--gold-ui); stroke-width: 1; stroke-dasharray: 2 3; opacity: .8; }
.pace-today-label { font-size: 9.5px; fill: var(--gold-ui); }

.k-class    { fill: var(--k-class); }
.k-holiday  { fill: var(--k-holiday); }
.k-revision { fill: var(--k-revision); }
.k-exam     { fill: var(--k-exam); }

.pace-legend {
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  font-size: 12px; color: var(--text-muted);
  margin-bottom: 12px;
}
.pace-legend .key { display: inline-flex; align-items: center; gap: 6px; }
.pace-legend .sw {
  width: 15px; height: 10px; border-radius: 2px; flex: none;
  background: var(--k-class);
}
.pace-legend .sw.k-holiday  { background: var(--k-holiday); }
.pace-legend .sw.k-revision { background: var(--k-revision); }
.pace-legend .sw.k-exam     { background: var(--k-exam); }
.pace-legend .sw.target {
  height: 0; border-top: 2px dashed var(--baseline); border-radius: 0; width: 18px;
}
.pace-legend .sw.mine {
  height: 0; border-top: 2.5px solid var(--accent); border-radius: 0; width: 18px;
}
.pace-status {
  margin-left: auto;
  font-weight: 600;
  color: var(--text-secondary);
  font-variant-numeric: tabular-nums;
}

.yr-table { width: 100%; border-collapse: collapse; font-size: 12.5px; }
.yr-table th {
  text-align: left; font-weight: 500; color: var(--text-muted);
  font-size: 11px; letter-spacing: .04em; text-transform: uppercase;
  padding: 6px 10px 6px 0; border-bottom: 1px solid var(--hairline);
}
.yr-table td {
  padding: 8px 10px 8px 0;
  font-variant-numeric: tabular-nums;
  color: var(--text-primary);
}
.yr-table .dot {
  display: inline-block; width: 9px; height: 9px; border-radius: 2px;
  margin-right: 7px; vertical-align: 0;
}
.yr-table .dot.k-class    { background: var(--k-class); }
.yr-table .dot.k-holiday  { background: var(--k-holiday); }
.yr-table .dot.k-revision { background: var(--k-revision); }
.yr-table .dot.k-exam     { background: var(--k-exam); }

@media (max-width: 620px) {
  .pace-status { margin-left: 0; flex: 1 0 100%; }
  .yr-table { font-size: 12px; }
  /* A year-long timeline squeezed into 320px is unreadable — scroll it
     instead, the way the old weekly chart did. */
  .pace-chart { overflow-x: auto; }
  .pace-chart svg { min-width: 720px; }
}

/* ---------------- reference codes ---------------- */
/* 1a.3 — year number, subject letter, unit number. A label, not a heading:
   it stays quiet enough that the title still reads first, and tabular figures
   keep a column of them aligned. */
.code {
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum";
  font-weight: 500;
  color: var(--text-muted);
  letter-spacing: .01em;
  white-space: nowrap;
  flex: none;
  text-decoration: none;
}
.year-titles h3 .code { margin-right: 9px; font-size: 14px; }
.subj-titles h4 .code { margin-right: 2px; font-size: 12.5px; }
.detail-title .code { margin-right: 8px; font-size: 13px; }
.f-unit .code { margin-right: 8px; font-size: 13px; }

/* On a unit the code sits in its own column between the tick and the title,
   so the numbers line up down the list however long the titles run. */
.u-code {
  font-size: 11.5px;
  min-width: 3.4em;
  padding-top: 2px;
  text-align: right;
}

.units { list-style: none; margin: 8px 0 0; padding: 0; }
.unit {
  display: flex; align-items: flex-start; gap: 11px;
  padding: 7px 16px;
  border-top: 1px solid var(--hairline);
  transition: background .1s;
}
.unit:hover { background: var(--surface-2); }
/* The label now wraps only the checkbox — the lesson text is its own button
   that opens the notes panel, so the label must not grow. */
.unit label { display: inline-flex; align-items: flex-start; flex: none; cursor: pointer; }

.box {
  flex: none;
  width: 17px; height: 17px;
  margin-top: 2px;
  border: 1.5px solid var(--baseline);
  border-radius: 5px;
  display: inline-flex; align-items: center; justify-content: center;
  transition: background .12s, border-color .12s;
}
.box svg { opacity: 0; transition: opacity .12s; }
/* Scoped to the label, not to the row: lesson rows use the same control, and
   scoping to .unit left their real input visible beside the drawn box. */
.u-check input { position: absolute; opacity: 0; width: 0; height: 0; }
.u-check input:focus-visible + .box { outline: 2px solid var(--accent); outline-offset: 2px; }
.u-check input:checked + .box { background: var(--accent); border-color: var(--accent); }
.u-check input:checked + .box svg { opacity: 1; }

/* A plain unit's title is just text now — notes open from the row's menu,
   so there is nothing to click and it should not look clickable. Units with
   lessons keep a real button, because that one still toggles the list. */
.u-text {
  font-size: 13.5px; min-width: 0; word-wrap: break-word;
  flex: 1;
  text-align: left;
}
span.u-text { cursor: default; }
button.u-text { cursor: pointer; }
/* The input lives inside .u-check, so it is not a sibling of the title —
   an earlier `~` selector here never matched and completed units never
   showed as done at all. :has() reaches it from the row instead. */
/* Nothing is done to the title itself when a row is finished — no line
   through it, no highlight behind it. The tick on the left and the green
   label on the right already say so, and both tried treatments made the
   list harder to read rather than easier. */
.u-date {
  font-size: 11px; color: var(--text-muted);
  flex: none; font-variant-numeric: tabular-nums; padding-top: 2px;
}
.u-del { flex: none; opacity: 0; transition: opacity .12s; }
.unit:hover .u-del { opacity: 1; }

.unit.custom .u-text::after {
  content: "added";
  font-size: 10px;
  color: var(--text-muted);
  border: 1px solid var(--border);
  border-radius: 20px;
  padding: 0 5px;
  margin-left: 7px;
  vertical-align: 1px;
  text-decoration: none;
  display: inline-block;
}

.subj-tools {
  display: flex; gap: 8px; flex-wrap: wrap;
  padding: 11px 16px;
  border-top: 1px solid var(--hairline);
  background: var(--surface-2);
}

/* books + notes */
.shelf { padding: 12px 16px; border-top: 1px solid var(--hairline); }
.shelf h5 {
  margin: 0 0 8px; font-size: 11px; font-weight: 600;
  color: var(--text-muted); text-transform: uppercase; letter-spacing: .07em;
}
.books { list-style: none; margin: 0 0 8px; padding: 0; display: grid; gap: 5px; }
.books li { display: flex; align-items: center; gap: 8px; font-size: 13px; }
.books a { text-decoration: none; }
.books a:hover { text-decoration: underline; }
.books .empty { color: var(--text-muted); font-size: 12.5px; }

.notes {
  width: 100%;
  min-height: 76px;
  resize: vertical;
  background: var(--plane);
  color: var(--text-primary);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 9px 11px;
  font: inherit;
  font-size: 13px;
}
.notes:focus { outline: 2px solid var(--accent); outline-offset: -1px; }

/* ---------------- misc ---------------- */

.note-bar {
  display: flex; gap: 10px; align-items: flex-start;
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  border-radius: var(--radius);
  padding: 12px 15px;
  font-size: 12.5px;
  color: var(--text-secondary);
  margin-top: 24px;
}
.note-bar strong { color: var(--text-primary); font-weight: 600; }

.empty-state {
  padding: 40px 20px;
  text-align: center;
  color: var(--text-muted);
  font-size: 13px;
}

.toast {
  position: fixed;
  left: 50%; bottom: 26px;
  transform: translateX(-50%) translateY(10px);
  background: var(--text-primary);
  color: var(--plane);
  padding: 9px 16px;
  border-radius: 8px;
  font-size: 13px;
  opacity: 0;
  pointer-events: none;
  transition: opacity .18s, transform .18s;
  z-index: 100;
  box-shadow: var(--shadow);
}
.toast.on { opacity: 1; transform: translateX(-50%) translateY(0); }

.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;
}

[dir="rtl"], .ar, .u-text:lang(ar) { }

/* table view (accessibility fallback for the charts) */
.table-view { margin-top: 12px; overflow-x: auto; }
.table-view table { border-collapse: collapse; width: 100%; font-size: 12.5px; }
.table-view th, .table-view td {
  text-align: left; padding: 5px 10px 5px 0;
  border-bottom: 1px solid var(--hairline);
}
.table-view th { color: var(--text-muted); font-weight: 500; }
.table-view td.num { font-variant-numeric: tabular-nums; }
.table-view[hidden] { display: none; }

/* ---------------- course materials ---------------- */

/* Chips on a lesson line: what is attached, at a glance. */
.mat-chips { display: inline-flex; gap: 4px; align-items: center; flex: none; }
.chip {
  display: inline-flex; align-items: center; gap: 2px;
  color: var(--gold-ui);
  background: var(--track);
  border-radius: 5px;
  padding: 1px 4px;
  line-height: 1;
}
.chip-video { color: var(--status-critical); }
.chip-done  { color: var(--success-text); background: none; font-size: 12px; font-weight: 700; }
.chip-n { font-size: 10px; font-weight: 600; }

/* The "+" on a lesson line — a visible way in for people who don't
   think to right-click. */
.u-add {
  flex: none;
  opacity: 0;
  transition: opacity .12s;
  font-size: 15px;
  line-height: 1;
  padding: 2px 7px;
  color: var(--text-muted);
}
.unit:hover .u-add, .u-add:focus-visible { opacity: 1; }
.u-add:hover { color: var(--gold-ui); background: var(--track); }

/* Right-click menu */
.ctx {
  position: fixed;
  z-index: 130;
  min-width: 232px;
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: 10px;
  box-shadow: var(--shadow);
  padding: 5px;
  font-size: 13px;
}
.ctx[hidden] { display: none; }
.ctx-head {
  font-size: 11px;
  color: var(--text-muted);
  padding: 5px 9px 7px;
  border-bottom: 1px solid var(--hairline);
  margin-bottom: 4px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 260px;
}
.ctx button {
  display: flex;
  align-items: center;
  gap: 9px;
  width: 100%;
  text-align: left;
  background: none;
  border: 0;
  border-radius: 6px;
  padding: 8px 9px;
  color: var(--text-primary);
}
.ctx-sep { height: 1px; background: var(--hairline); margin: 5px 2px; }
.ctx button:hover { background: var(--surface-2); color: var(--gold-ui); }
.ctx button svg { flex: none; color: var(--text-muted); }
.ctx button:hover svg { color: var(--gold-ui); }

/* Drop target feedback */
.drop-hot {
  outline: 2px dashed var(--gold-ui);
  outline-offset: -2px;
  background: var(--surface-2) !important;
  border-radius: 6px;
}

.drop-hint {
  font-size: 12px;
  color: var(--text-muted);
  margin: 8px 0 10px;
  max-width: 62ch;
}

/* Material rows */
.mat-list { list-style: none; margin: 0; padding: 0; }
.unit + .mat-list { background: var(--plane); }
.mat {
  display: flex; align-items: center; gap: 11px;
  padding: 9px 16px 9px 44px;
  border-top: 1px solid var(--hairline);
  font-size: 13px;
}
.shelf .mat { padding-left: 16px; }
.mat:hover { background: var(--surface-2); }

.mat-icon {
  flex: none;
  width: 26px; height: 26px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 6px;
  background: var(--track);
  color: var(--gold-ui);
}
.mat-icon.kind-video { color: var(--status-critical); }

.mat-thumb {
  flex: none;
  position: relative;
  width: 64px; height: 36px;
  border-radius: 5px;
  overflow: hidden;
  display: block;
  background: var(--surface-2);
}
.mat-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.mat-thumb .play {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  color: #fff;
  background: rgba(0, 0, 0, .3);
}

.mat-body { flex: 1; min-width: 0; }
.mat-title {
  font-weight: 500;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.mat-prog { display: flex; align-items: center; gap: 8px; margin-top: 3px; }
.mat-prog .meter { max-width: 130px; }
.mat-pages { font-size: 11.5px; color: var(--text-muted); white-space: nowrap; }

.mat-actions { display: flex; gap: 5px; align-items: center; flex: none; }
.mat-actions a.btn { text-decoration: none; display: inline-flex; align-items: center; }

/* ---------------- the PDF reader ---------------- */

body.reading { overflow: hidden; }

.reader {
  position: fixed; inset: 0;
  z-index: 120;
  background: var(--plane);
  display: flex;
  flex-direction: column;
}
.reader[hidden] { display: none; }

.reader-bar {
  display: flex; align-items: center; gap: 12px;
  padding: 10px 14px;
  background: var(--surface-1);
  border-bottom: 1px solid var(--hairline);
  flex: none;
  flex-wrap: wrap;
}
.reader-title {
  font-weight: 600; font-size: 14px;
  flex: 1; min-width: 120px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.reader-nav, .reader-right { display: flex; align-items: center; gap: 6px; flex: none; }
.rd-page {
  width: 62px;
  background: var(--plane);
  color: var(--text-primary);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 4px 7px;
  font: inherit; font-size: 13px;
  text-align: center;
  font-variant-numeric: tabular-nums;
}
.rd-of { font-size: 12px; color: var(--text-muted); white-space: nowrap; }
.reader-right a.btn { text-decoration: none; }

.reader-stage {
  flex: 1;
  overflow: auto;
  display: flex;
  justify-content: center;
  align-items: flex-start;
  padding: 16px;
  background: var(--plane);
}
.reader.loading .reader-stage::before {
  content: "Loading…";
  color: var(--text-muted);
  font-size: 13px;
  align-self: center;
  margin-top: 18vh;
}
.reader-stage canvas {
  box-shadow: var(--shadow);
  border-radius: 3px;
  background: #fff;
  max-width: 100%;
  height: auto;
}

.reader-foot {
  flex: none;
  display: flex; align-items: center; gap: 10px;
  padding: 8px 14px;
  background: var(--surface-1);
  border-top: 1px solid var(--hairline);
  font-size: 12px;
  color: var(--text-muted);
}
.reader-foot .meter { flex: 1; width: auto; }

/* ==================================================================
   Lessons — the sub-list under a topic, and the slide viewer.
   ================================================================== */

/* A topic that has lessons gets a chevron and reads as a disclosure. */
.unit.has-lessons > .u-text { display: flex; align-items: baseline; gap: 8px; }
.unit.has-lessons > .u-text .chev {
  color: var(--text-muted);
  transition: transform .15s;
  flex: none;
  align-self: center;
  display: inline-flex;
}
.unit.lessons-open > .u-text .chev { transform: rotate(90deg); }
.unit.lessons-open { background: var(--surface-2); }
/* How much of a topic is behind you: every lesson read and every quiz sat.
   Small enough to sit on the row without competing with the title. */
.topic-prog {
  display: inline-flex; align-items: center; gap: 6px;
  flex: none;
  text-decoration: none;
  vertical-align: 1px;
}
.topic-meter {
  width: 46px; height: 5px;
  border-radius: 3px;
  background: var(--track);
  overflow: hidden;
  display: inline-block;
}
.topic-fill {
  display: block; height: 100%;
  background: var(--accent);
  border-radius: 3px;
  transition: width .3s cubic-bezier(.32, .72, 0, 1);
}
.topic-n {
  font-size: 10.5px;
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.topic-prog.full .topic-n { color: var(--success-text); }

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

.lesson-panel { display: none; }
.unit.lessons-open + .lesson-panel { display: block; }
.lesson-list {
  list-style: none;
  margin: 0;
  padding: 6px 16px 10px 44px;
  background: var(--plane);
  border-top: 1px solid var(--hairline);
  display: grid;
  gap: 6px;
}
/* Lesson rows carry their own tick, so the list reads like the unit rows
   above it. The spacer keeps quizzes and pending lessons in the same left
   gutter without giving them a box they cannot use. */
.lesson { margin: 0; display: flex; align-items: center; gap: 10px; }
.lesson .lesson-open { flex: 1; min-width: 0; }
.lesson-check { flex: none; align-self: center; }
.lesson-spacer { flex: none; width: 17px; }

/* A finished lesson keeps its colour; the tick and the label carry it. */
.lesson.done .lesson-title { color: var(--text-primary); }
.lesson-open {
  display: flex; align-items: center; gap: 11px;
  width: 100%;
  text-align: left;
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 9px 12px;
  color: var(--text-primary);
  cursor: pointer;
  transition: border-color .12s, background .12s;
}
.lesson-open:hover { border-color: var(--gold-ui); background: var(--surface-2); }
.lesson-open:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

.lesson-icon {
  flex: none;
  width: 28px; height: 28px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 7px;
  background: var(--track);
  color: var(--gold-ui);
}
.lesson-body { flex: 1; min-width: 0; display: block; }
.lesson-title { display: block; font-size: 13px; font-weight: 500; }
.lesson-sub { display: block; font-size: 11.5px; color: var(--text-muted); }
.lesson-cta {
  flex: none;
  font-size: 11.5px;
  font-weight: 600;
  color: var(--gold-ui);
  white-space: nowrap;
}
/* Done reads as a statement, not an invitation — so it drops the accent and
   takes the completion colour the rest of the page uses. */
.lesson-cta.is-done { color: var(--success-text); font-weight: 500; }
/* Started but not finished is a statement too, just not a claim. */
.lesson-cta.is-going { color: var(--text-muted); font-weight: 500; }


.lesson.pending {
  gap: 10px;
  color: var(--text-muted);
}
.lesson.pending .lesson-icon,
.lesson.pending .lesson-body {
  align-self: center;
}
/* The dashed frame belongs round the content, not the gutter. */
.lesson.pending .lesson-body {
  flex: 1;
  padding: 9px 12px 9px 0;
}
.lesson.pending .lesson-icon { background: transparent; color: var(--text-muted); }

/* Quizzes wear green so a glance down the list separates them from the
   lessons without reading a word. --correct-bg is the validated green from
   the quiz feedback, and already clears 4.5:1 with white on it. */
.quiz-link .lesson-icon {
  background: var(--correct-bg);
  color: #fff;
}
.lesson.quiz-link .lesson-open:hover .lesson-icon { background: var(--correct-bg); }
.lesson.pending .lesson-title { font-weight: 500; color: var(--text-secondary); }

/* ---------------- the slide viewer ---------------- */

.deck {
  position: fixed; inset: 0;
  z-index: 130;
  background: var(--plane);
  display: flex;
  flex-direction: column;
}
.deck[hidden] { display: none; }

.deck-bar {
  display: flex; align-items: center; gap: 12px;
  padding: 10px 14px;
  background: var(--surface-1);
  border-bottom: 1px solid var(--hairline);
  flex: none;
  flex-wrap: wrap;
}
.deck-heading { flex: 1; min-width: 120px; overflow: hidden; }
.deck-lesson {
  display: block;
  font-weight: 600; font-size: 14px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.deck-slide {
  display: block;
  font-size: 12px; color: var(--text-muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.deck-nav, .deck-right { display: flex; align-items: center; gap: 6px; flex: none; }
.deck-nav .btn { display: inline-flex; align-items: center; padding: 4px 9px; }
.dk-count {
  font-size: 12px; color: var(--text-muted);
  font-variant-numeric: tabular-nums;
  min-width: 54px; text-align: center;
}

.deck-main {
  flex: 1;
  position: relative;
  overflow: hidden;
  background: var(--plane);
}
/* The stage keeps its native pixel size and is scaled to fit, so nothing
   inside it ever reflows — a slide looks the same at every size. */
.deck-fit {
  position: absolute;
  left: 50%; top: 50%;
  transform-origin: 50% 50%;
}
.deck-fit .slide-stage {
  border-radius: 4px;
  box-shadow: var(--shadow);
}

/* ---------------- the quiz ---------------- */
/* Not drawn on the slide stage: it has to stay legible and tappable at any
   size, which a fixed 1280-wide canvas scaled to a phone would not. */

.deck-quiz {
  position: absolute; inset: 0;
  overflow: auto;
  padding: 20px 16px 28px;
}
.deck-quiz[hidden] { display: none; }

.quiz { max-width: 860px; margin: 0 auto; }

.quiz-head {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 16px; flex-wrap: wrap;
  margin-bottom: 18px;
}
.quiz-mode { display: block; font-size: 17px; font-weight: 600; }
.quiz-hint { display: block; font-size: 12.5px; color: var(--text-muted); margin-top: 2px; }
.quiz-track { flex: none; min-width: 190px; text-align: right; }
.quiz-round {
  display: block;
  font-size: 12px; color: var(--text-muted);
  font-variant-numeric: tabular-nums;
  margin-bottom: 5px;
}
.quiz-track .meter { width: 100%; }

/* The cards, with the progress column beside them. */
.quiz-body { display: flex; align-items: stretch; gap: 14px; }
.quiz-body .quiz-rows { flex: 1; min-width: 0; }

.vbar {
  flex: none;
  width: 34px;
  display: flex; flex-direction: column; align-items: center; gap: 7px;
}
.vbar-track {
  position: relative;
  flex: 1;
  width: 9px;
  border-radius: 5px;
  background: var(--track);
  overflow: hidden;
}
/* Fills upward — the thermometer reading everyone already knows. */
.vbar-fill {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  background: var(--accent);
  border-radius: 5px;
  transition: height .35s cubic-bezier(.32, .72, 0, 1);
}
.vbar-half {
  position: absolute;
  left: 0; right: 0; bottom: 50%;
  height: 1px;
  background: var(--surface-1);
  opacity: .8;
}
.vbar-pct {
  font-size: 10.5px;
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}

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

.quiz-rows { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; }
.quiz-row {
  display: flex; align-items: center; gap: 14px;
  padding: 10px 14px;
  background: var(--surface-1);
  border: 1px solid var(--hairline);
  border-radius: 10px;
}
.quiz-n {
  flex: none;
  width: 22px; height: 22px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 50%;
  background: var(--track);
  color: var(--text-secondary);
  font-size: 11px;
  font-variant-numeric: tabular-nums;
}
.quiz-prompt {
  flex: 1 1 40%; min-width: 0;
  font-size: 16px;
  overflow-wrap: break-word;
}
.quiz-prompt.big { font-size: 30px; line-height: 1.5; }
.q-ar {
  unicode-bidi: isolate;
  direction: rtl;
  font-family: var(--ar-face);
}

/* The card: a plain rectangle until you turn it over. */
.quiz-card {
  flex: 1 1 46%;
  min-width: 0;
  /* Tall enough for the vowelled Arabic answer — harakat sit well above the
     letters, and a box sized to the English would clip them. */
  min-height: 78px;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  perspective: 900px;
}
.quiz-card:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 9px; }

.quiz-card-in {
  position: relative;
  display: block;
  width: 100%;
  /* Tall enough for the vowelled Arabic answer — harakat sit well above the
     letters, and a box sized to the English would clip them. */
  min-height: 78px;
  transform-style: preserve-3d;
  transition: transform .5s cubic-bezier(.2, .75, .3, 1);
}
.quiz-row.on .quiz-card-in { transform: rotateX(180deg); }

.quiz-face, .quiz-back {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  /* Tall enough for the vowelled Arabic answer — harakat sit well above the
     letters, and a box sized to the English would clip them. */
  min-height: 78px;
  padding: 8px 12px;
  border-radius: 9px;
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
}
.quiz-face {
  border: 1.5px dashed var(--baseline);
  background: var(--surface-2);
  color: var(--text-muted);
  font-size: 12px;
  letter-spacing: .04em;
  text-transform: uppercase;
}
.quiz-card:hover .quiz-face { border-color: var(--gold-ui); color: var(--gold-ui); }

.quiz-back {
  position: absolute; inset: 0;
  transform: rotateX(180deg);
  border: 1.5px solid var(--gold-400);
  background: var(--surface-2);
}
.quiz-answer { font-size: 16px; font-weight: 600; color: var(--text-primary); text-align: center; }
.quiz-answer.big { font-size: 27px; font-weight: 700; line-height: 1.5; }
.quiz-gloss { font-size: 11.5px; color: var(--text-muted); text-align: center; }

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

/* Self-marking. The buttons mean nothing until the answer is showing, so
   they only appear once the card has been turned over. */
.marks {
  flex: none;
  display: flex; gap: 6px;
  opacity: 0;
  pointer-events: none;
  transition: opacity .2s .25s;
}
.quiz-row.on .marks { opacity: 1; pointer-events: auto; }

.mark-btn {
  width: 34px; height: 34px;
  display: inline-flex; align-items: center; justify-content: center;
  padding: 0;
  border: 1.5px solid var(--border);
  border-radius: 9px;
  background: var(--surface-1);
  color: var(--text-muted);
  transition: background .12s, border-color .12s, color .12s;
}
.mark-btn .mark { width: 17px; height: 17px; display: block; }
.mark-btn.yes:hover { border-color: var(--correct-bg); color: var(--success-text); }
.mark-btn.no:hover  { border-color: var(--danger-bg);  color: var(--status-critical); }
.mark-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.mark-btn.yes[aria-pressed="true"] {
  background: var(--correct-bg); border-color: var(--correct-bg); color: #fff;
}
.mark-btn.no[aria-pressed="true"] {
  background: var(--danger-bg); border-color: var(--danger-bg); color: #fff;
}

/* A marked row carries its verdict on its edge, so a glance down the five
   shows how the round went without reading every card. */
.quiz-row.marked { border-left-width: 3px; }
.quiz-row.got  { border-left-color: var(--correct-bg); }
.quiz-row.miss { border-left-color: var(--danger-bg); }

/* The shortcut for a round you got clean. */
.btn.ok { display: inline-flex; align-items: center; gap: 5px; }
.btn.ok .mark { width: 13px; height: 13px; flex: none; color: var(--success-text); }
.btn.ok:hover { border-color: var(--correct-bg); }
.btn.ok:disabled { opacity: .45; cursor: default; }
.btn.ok:disabled:hover { border-color: var(--border); background: var(--surface-1); }

.done-saved {
  flex: 1;
  font-size: 12.5px;
  color: var(--success-text);
  display: inline-flex; align-items: center; gap: 6px;
}
.done-saved .mark { width: 14px; height: 14px; flex: none; }

.quiz-foot {
  display: flex; align-items: center; gap: 12px;
  margin-top: 20px;
}
.quiz-count {
  flex: 1;
  font-size: 12px; color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}

/* ---------------- the multiple-choice quiz ---------------- */

.quiz-tally { display: block; font-size: 12px; color: var(--text-muted); margin-top: 5px; }
.quiz-tally .ok { color: var(--success-text); }
.quiz-tally .no { color: var(--status-critical); }

.cloze {
  padding: 26px 22px;
  margin-bottom: 22px;
  background: var(--surface-1);
  border: 1px solid var(--hairline);
  border-radius: 12px;
  text-align: center;
}
.cloze-ar {
  margin: 0;
  font-family: var(--ar-face);
  font-size: 30px;
  line-height: 1.9;
}
/* The blank the verb came out of — sized to look like a word, not a hyphen. */
.cloze-gap {
  display: inline-block;
  width: 3.6em;
  height: .72em;
  margin: 0 .12em;
  vertical-align: -.04em;
  border-bottom: 2.5px dashed var(--gold-ui);
  border-radius: 2px;
  background: linear-gradient(var(--track), var(--track)) no-repeat center / 100% 60%;
}
.cloze-en {
  margin: 12px 0 0;
  font-size: 15px;
  color: var(--text-secondary);
  font-style: italic;
}
.cloze-cue { margin: 8px 0 0; font-size: 12.5px; color: var(--text-muted); }
.cloze-cue b { color: var(--gold-ui); font-weight: 600; }

.choices {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 10px;
}
.choice {
  position: relative;
  display: flex; align-items: center; justify-content: center;
  min-height: 74px;
  padding: 10px 40px;
  background: var(--surface-1);
  border: 1.5px solid var(--border);
  border-radius: 10px;
  color: var(--text-primary);
  cursor: pointer;
  transition: border-color .12s, background .12s;
}
.choice:hover { border-color: var(--gold-ui); background: var(--surface-2); }
.choice:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.choice-word { font-size: 26px; line-height: 1.6; }
.choice-mark {
  position: absolute;
  right: 12px; top: 50%;
  transform: translateY(-50%);
  width: 20px; height: 20px;
}
.choice-mark .mark { width: 100%; height: 100%; display: block; }

/* Right: hold the green and the tick while the next question loads. */
.choice.right {
  background: var(--correct-bg);
  border-color: var(--correct-bg);
  color: #fff;
}
/* Wrong: flash red with a cross, then settle back to where it started, so
   the option stays available and nothing is permanently marked. */
.choice.wrong { animation: choice-wrong .9s ease-out; }
.choice.wrong .choice-mark { animation: choice-mark .9s ease-out; }

@keyframes choice-wrong {
  0%, 55% {
    background: var(--danger-bg);
    border-color: var(--danger-bg);
    color: #fff;
  }
  100% {
    background: var(--surface-1);
    border-color: var(--border);
    color: var(--text-primary);
  }
}
@keyframes choice-mark {
  0%, 55% { opacity: 1; }
  100%    { opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .choice.wrong { animation-duration: .01s; }
  .choice.wrong .choice-mark { animation: none; opacity: 0; }
}

/* ---------------- the score at the end ---------------- */

.quiz.done { max-width: 620px; text-align: center; }
.done-score { margin: 26px 0 22px; }
.done-pct {
  display: block;
  font-size: 68px;
  font-weight: 700;
  line-height: 1;
  letter-spacing: -.02em;
  font-variant-numeric: tabular-nums;
  color: var(--gold-ui);
}
.done-line { display: block; margin-top: 10px; font-size: 13.5px; color: var(--text-secondary); }
.done-line .ok { color: var(--success-text); }
.done-line .no { color: var(--status-critical); }

.done-revisit {
  text-align: left;
  background: var(--surface-1);
  border: 1px solid var(--hairline);
  border-radius: 12px;
  padding: 16px 18px;
}
.done-revisit h4 {
  margin: 0 0 10px;
  font-size: 12px;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--text-muted);
  font-weight: 600;
}
.done-revisit ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }
.done-revisit li {
  display: flex; align-items: baseline; gap: 10px;
  font-size: 21px;
  padding-bottom: 8px;
  border-bottom: 1px solid var(--hairline);
}
.done-revisit li:last-child { border-bottom: 0; padding-bottom: 0; }
.done-en { font-size: 13px; color: var(--text-secondary); flex: 1; }
.done-n { font-size: 11.5px; color: var(--status-critical); white-space: nowrap; }
.done-clean { font-size: 14px; color: var(--success-text); margin: 0; }

.quiz.done .quiz-foot { justify-content: center; }
.quiz.done .quiz-count { flex: none; }

/* Scores on the syllabus lesson row. */
.score-pct { color: var(--gold-ui); font-weight: 600; }
.lesson-sub .q-ar { font-size: 13px; }

/* A quiz belongs to the lesson above it, so it sits indented under it rather
   than reading as another lesson. */
.lesson.quiz-link { margin-left: 26px; position: relative; }
.lesson.quiz-link::before {
  content: "";
  position: absolute;
  left: -14px; top: -4px; bottom: 50%;
  width: 9px;
  border-left: 1px solid var(--hairline);
  border-bottom: 1px solid var(--hairline);
  border-bottom-left-radius: 6px;
}
.lesson.quiz-link .lesson-open { background: var(--plane); }
.lesson.quiz-link .lesson-title { font-weight: 400; }

/* ---------------- past attempts ---------------- */
/* One line per sitting. Six hues, assigned by attempt number and never
   cycled — a seventh attempt drops an older middle line rather than reusing
   a colour. Every line also carries a dash pattern, a marker shape and a
   number at its end, so identity never rests on hue alone.

   Attempt 1 green and attempt 2 gold were asked for, and they are the pair
   this palette otherwise avoids (see the note at the top of this file). Both
   were re-stepped for lightness until the validator passed: worst adjacent
   CVD separation is ΔE 8.6 light, 10.1 dark, against these exact surfaces. */
.attempts {
  --series-1: #0b6b30;   /* green  — attempt 1 */
  --series-2: #ad7d09;   /* gold   — attempt 2 */
  --series-3: #2a78d6;
  --series-4: #c0398f;
  --series-5: #6b3fb5;
  --series-6: #c2521f;
  max-width: 860px;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .attempts {
    --series-1: #1f7a3f;
    --series-2: #b58c3a;
    --series-3: #5b93de;
    --series-4: #d264a0;
    --series-5: #7d68d4;
    --series-6: #d1734a;
  }
}
:root[data-theme="dark"] .attempts {
  --series-1: #1f7a3f;
  --series-2: #b58c3a;
  --series-3: #5b93de;
  --series-4: #d264a0;
  --series-5: #7d68d4;
  --series-6: #d1734a;
}

.att-chart {
  background: var(--surface-1);
  border: 1px solid var(--hairline);
  border-radius: 12px;
  padding: 10px 6px 4px;
  margin-bottom: 14px;
}

.att-chart .gridline { stroke: var(--hairline); stroke-width: 1; }
.att-chart .ax-value, .att-chart .ax-label {
  font-size: 10.5px; fill: var(--text-muted); font-variant-numeric: tabular-nums;
}
.att-chart .ax-title { font-size: 10.5px; fill: var(--text-muted); }

/* The reference: a perfect round, every round. Grey and dashed so it reads
   as a target rather than as another attempt. */
.att-chart .perfect {
  stroke: var(--baseline);
  stroke-width: 2;
  stroke-dasharray: 7 5;
}
.att-chart .perfect-label { font-size: 10.5px; fill: var(--text-muted); }

.att { fill: none; stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.att.pt { stroke-width: 1.6; }
.att.pt > * { fill: currentColor; stroke: var(--surface-1); }
.att.pt > .hollow { fill: var(--surface-1); stroke: currentColor; stroke-width: 2; }
/* An attempt with no round detail: a straight line at its average pace,
   dotted so it never passes for a measured one. */
.att.est { stroke-dasharray: 2 4; opacity: .8; }
.att.muted { opacity: .22; }

/* Dash and marker per slot, so the lines stay tellable apart in greyscale,
   in print, and under forced colours. */
.a1 { stroke: var(--series-1); color: var(--series-1); }
.a2 { stroke: var(--series-2); color: var(--series-2); stroke-dasharray: 8 4; }
.a3 { stroke: var(--series-3); color: var(--series-3); stroke-dasharray: 2 3.5; }
.a4 { stroke: var(--series-4); color: var(--series-4); stroke-dasharray: 11 3 2 3; }
.a5 { stroke: var(--series-5); color: var(--series-5); stroke-dasharray: 14 5; }
.a6 { stroke: var(--series-6); color: var(--series-6); stroke-dasharray: 4 3; }
.att.pt, .att-swatch .pt { stroke-dasharray: none; }

/* Text wears text tokens; the number at a line's end is the exception that
   has to match its line, so it carries the hue and nothing else does. */
.att-end {
  font-size: 11px; font-weight: 600;
  font-variant-numeric: tabular-nums;
  fill: currentColor;
}

.att-legend {
  display: flex; flex-wrap: wrap; gap: 8px;
  align-items: center;
  margin-bottom: 14px;
}
.att-key {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 5px 11px 5px 7px;
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: 20px;
  font-size: 12.5px;
  color: var(--text-secondary);
}
.att-key:hover { border-color: var(--gold-ui); color: var(--text-primary); }
.att-key.on { border-color: var(--accent); background: var(--surface-2); color: var(--text-primary); }
.att-key:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.att-swatch { width: 26px; height: 12px; flex: none; overflow: visible; }
.att-pct { font-variant-numeric: tabular-nums; color: var(--text-muted); }
.att-more { font-size: 11.5px; color: var(--text-muted); }

.att-detail {
  background: var(--surface-1);
  border: 1px solid var(--hairline);
  border-radius: 12px;
  padding: 14px 18px;
  margin-bottom: 14px;
}
.att-detail h4 {
  margin: 0 0 10px;
  font-size: 12px; letter-spacing: .06em; text-transform: uppercase;
  color: var(--text-muted); font-weight: 600;
}
.att-detail ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }
.att-detail li {
  display: flex; align-items: baseline; gap: 10px;
  font-size: 20px;
  padding-bottom: 8px;
  border-bottom: 1px solid var(--hairline);
}
.att-detail li:last-child { border-bottom: 0; padding-bottom: 0; }

.attempts .table-view table { font-variant-numeric: tabular-nums; }
.attempts .table-view td { white-space: nowrap; }

.deck-thumb.is-quiz {
  display: flex; align-items: center; justify-content: center;
  font-size: 12px; font-weight: 600;
  color: var(--text-secondary);
  background: var(--surface-2);
  border-style: dashed;
  border-color: var(--baseline);
}
.deck-thumb.is-quiz.on { border-style: solid; border-color: var(--accent); color: var(--gold-ui); }

.deck-notes {
  flex: none;
  max-height: 26vh;
  overflow: auto;
  padding: 12px 18px;
  background: var(--surface-1);
  border-top: 1px solid var(--hairline);
  font-size: 13px;
  color: var(--text-secondary);
  white-space: pre-wrap;
}
.deck-notes[hidden] { display: none; }

.deck-rail {
  flex: none;
  display: flex; gap: 8px;
  padding: 9px 12px;
  overflow-x: auto;
  background: var(--surface-1);
  border-top: 1px solid var(--hairline);
  scrollbar-width: thin;
}
.deck-thumb {
  position: relative;
  flex: none;
  width: 132px; height: 74px;
  padding: 0;
  overflow: hidden;
  border: 2px solid transparent;
  border-radius: 5px;
  background: var(--surface-2);
  cursor: pointer;
}
.deck-thumb:hover { border-color: var(--baseline); }
.deck-thumb.on { border-color: var(--accent); }
.deck-thumb:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.deck-thumb-in {
  position: absolute; left: 0; top: 0;
  transform-origin: 0 0;
  display: block;
  pointer-events: none;
}
.deck-thumb-n {
  position: absolute; right: 3px; bottom: 2px;
  font-size: 10px;
  font-variant-numeric: tabular-nums;
  color: #fff;
  background: rgba(0, 0, 0, .55);
  border-radius: 3px;
  padding: 0 4px;
}

/* ---------------- a slide ---------------- */
/* Everything below is the converted deck's own design, not the site's —
   the generator writes absolute positions and literal colours, so these
   rules only supply what every slide needs. */
.slide-stage {
  position: relative;
  overflow: hidden;
  font-family: Arial, Helvetica, sans-serif;
  font-size: 24px;
  line-height: 1.2;
  color: #000;
  text-align: left;
  direction: ltr;
  --slide-ar: var(--ar-face);
}
.slide-stage .sh { position: absolute; }
.slide-stage .tx {
  position: absolute; inset: 0;
  display: flex; flex-direction: column;
}
.slide-stage p { margin: 0; }
.slide-stage .ar { unicode-bidi: isolate; font-family: var(--slide-ar); }
.slide-stage .bu { position: absolute; }
.slide-stage .edge { position: absolute; inset: 0; width: 100%; height: 100%; }
.slide-stage .tb {
  position: absolute;
  border-collapse: collapse;
  table-layout: fixed;
  font-size: 24px;
}
.slide-stage .tb td { padding: 0; }

@media (max-width: 620px) {
  .deck-heading { flex: 1 0 100%; order: -1; }
  .deck-thumb { width: 104px; height: 59px; }
  .lesson-list { padding-left: 16px; }

  /* Prompt over card rather than beside it — side by side leaves neither
     enough width to read a vowelled verb. */
  .quiz-row { flex-wrap: wrap; gap: 8px 12px; }
  .quiz-prompt { flex: 1 1 auto; }
  .quiz-prompt.big { font-size: 26px; }
  .quiz-card { flex: 1 1 auto; }
  .vbar { width: 22px; }
  .quiz-track { text-align: left; min-width: 0; flex: 1 0 100%; }
  .deck-quiz { padding: 16px 12px 24px; }
  .choices { grid-template-columns: 1fr; }
  .quiz-foot { flex-wrap: wrap; }
}

/* ---------------- narrow screens ---------------- */
/* The fixed-width meter crushes the titles below ~620px, so drop it onto
   its own full-width row underneath. */
@media (max-width: 1100px) {
  .wrap, .wrap-wide, .masthead-in { padding-left: 24px; padding-right: 24px; }
}

@media (max-width: 620px) {
  .wrap, .wrap-wide, .masthead-in { padding-left: 14px; padding-right: 14px; }
  .year-head, .subj-head { flex-wrap: wrap; row-gap: 10px; }
  /* Chevron stays beside the title; only the meter drops to its own row. */
  .year-titles, .subj-titles { flex: 1 1 auto; min-width: 0; }
  .year-stat, .subj-stat { flex: 1 0 100%; }
  .year-stat .meter, .subj-stat .meter { flex: 1; width: auto; }
  .subj-titles p { white-space: normal; }

  /* Keep the chart legible instead of shrinking the type — scroll it. */
  .chart svg { min-width: 520px; }

  .masthead-in { gap: 10px; }
  .search { flex: 1 1 100%; width: auto; }
  .brand { margin-right: 0; }
  .tiles { grid-template-columns: repeat(auto-fit, minmax(132px, 1fr)); }
  .unit { padding-left: 12px; padding-right: 12px; }
}

@media print {
  .masthead, .toolbar, .subj-tools, .u-del { display: none !important; }
  .year-body, .subj-body { display: block !important; }
}

/* ---------------- syllabus + detail panel ---------------- */

/* No selection, no panel — the syllabus gets the full width.
   The second track is kept at 0px rather than removed: grid-template-columns
   only interpolates between track lists of the SAME length, so dropping to a
   single track would make the width snap instead of slide. */
.syllabus-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 0px;
  gap: 0;
  align-items: start;
  transition: grid-template-columns .3s cubic-bezier(.32, .72, 0, 1),
              gap .3s cubic-bezier(.32, .72, 0, 1);
}
.syllabus-grid.with-detail {
  grid-template-columns: minmax(0, 1fr) 460px;
  gap: 22px;
}
.syllabus-grid > * { min-width: 0; }

/* Mounted = in the DOM and taking space; `in` = faded/slid into place.
   The two are separate so the close animation can play before unmounting. */
.detail { display: none; }
.detail.mounted { display: block; }

/* The panel is meant to read as an extension of the row you clicked:
   same surface, same border, joined by a notch pointing back at it. */
.detail {
  position: sticky;
  top: 70px;
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  /* No overflow here — it would clip the notch hanging off the left edge.
     The inner element does the scrolling instead. */
  transition: background .15s, border-color .15s;
}
.detail.open {
  background: var(--surface-2);
  border-color: var(--gold-ui);
}
.detail .notch {
  position: absolute;
  left: -7px;
  width: 12px; height: 12px;
  background: var(--surface-2);
  border-left: 1px solid var(--gold-ui);
  border-bottom: 1px solid var(--gold-ui);
  transform: rotate(45deg);
  opacity: 0;
  transition: top .2s cubic-bezier(.32,.72,0,1), opacity .2s ease .12s;
  pointer-events: none;
}
.detail.in .notch { opacity: 1; }
/* Sized to what is in it, not to the window. It used to be a full-height
   column with the notes box flexed to fill the leftover — which made an empty
   note a full screen of empty box. It grows with the writing instead, and only
   starts scrolling once there is more than a screenful.

   Still a flex column: that is what lets the attachments sit under the notes
   without either one measuring the other. An earlier version measured
   scrollHeight per keystroke, which reports nonsense inside this transformed
   panel — flex removes the arithmetic entirely. */
.detail-in {
  position: relative;
  display: flex;
  flex-direction: column;
  padding: 18px 20px 20px;
  max-height: calc(100vh - 92px);
  overflow-y: auto;
  border-radius: var(--radius);
  opacity: 0;
  transform: translateX(-14px) scale(.97);
  transform-origin: left center;
  transition: opacity .2s ease, transform .3s cubic-bezier(.32, .72, 0, 1);
}
.detail.in .detail-in {
  opacity: 1;
  transform: none;
  transition-delay: .05s;   /* let the column start opening first */
}

.detail-close {
  position: absolute;
  top: 12px; right: 12px;
  background: none;
  border: 0;
  font-size: 20px;
  line-height: 1;
  padding: 2px 6px;
  border-radius: 6px;
  color: var(--text-muted);
}
.detail-close:hover { background: var(--surface-1); color: var(--text-primary); }
.detail-empty {
  padding: 26px 18px;
  font-size: 12.5px;
  color: var(--text-muted);
  text-align: center;
}
.detail-crumb {
  font-size: 11px;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: .06em;
  margin-bottom: 5px;
}
.detail-title {
  margin: 0 0 16px;
  padding-right: 26px;
  font-size: 16px;
  font-weight: 600;
  line-height: 1.35;
  letter-spacing: -0.01em;
}
.detail-label {
  display: block;
  font-size: 11px;
  font-weight: 600;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: .07em;
  margin-bottom: 6px;
}
.detail-head { flex: none; }

/* A few lines to start with, and draggable if you want more. It does not
   stretch to the bottom of the window — an empty note should look like an
   empty note, not a blank page. */
.detail .notes {
  flex: none;
  min-height: 120px;
  height: 148px;
  max-height: 52vh;
  background: var(--surface-1);
  line-height: 1.6;
  resize: vertical;
  overflow-y: auto;
}
/* Attachments sit under the notes and take the room they need; the panel as
   a whole scrolls if that runs long. */
.detail-mats {
  flex: none;
  margin-top: 16px;
}
.detail-mats .mat { padding-left: 0; padding-right: 0; }
.detail-mats .mat-list { background: none; }

/* The clicked row wears the panel's colour so the two read as one object. */
.unit, .subj-head, .year-head {
  transition: background .2s ease, box-shadow .2s ease;
}
.row-active,
.unit.row-active,
.subj-head.row-active {
  background: var(--surface-2) !important;
  box-shadow: inset 2px 0 0 var(--gold-ui);
}

/* Unit rows: the checkbox ticks; a topic with lessons opens its list. */
button.u-text {
  min-width: 0;
  background: none;
  border: 0;
  padding: 0;
  font: inherit;
  font-size: 13.5px;
  color: inherit;
  word-wrap: break-word;
}
button.u-text:hover { color: var(--gold-ui); }
.has-note { color: var(--text-muted); vertical-align: 1px; margin-left: 5px; }

.subj-mats { border-top: 1px solid var(--hairline); }
.subj-mats .mat-list { background: var(--plane); }

@media (max-width: 1000px) {
  .syllabus-grid, .syllabus-grid.with-detail { grid-template-columns: 1fr; gap: 0; }
  .detail {
    position: fixed;
    left: 12px; right: 12px; bottom: 12px;
    top: auto;
    z-index: 100;
    display: none;
  }
  .detail-in { height: 62vh; }
  .detail.open { display: block; }
  .detail .notch { display: none; }
}

/* Honour the OS setting — no sliding for anyone who asked for less motion. */
@media (prefers-reduced-motion: reduce) {
  .syllabus-grid,
  .detail-in,
  .detail .notch,
  .unit, .subj-head, .year-head,
  .meter .fill {
    transition: none !important;
  }
  .detail-in { opacity: 1; transform: none; }
}

/* ---------------- dialogs ---------------- */

.modal-back {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  background: rgba(4, 12, 8, .55);
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
  opacity: 0;
  transition: opacity .16s ease;
}
.modal-back[hidden] { display: none; }
.modal-back.in { opacity: 1; }

.modal {
  width: 100%;
  max-width: 430px;
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: 14px;
  box-shadow: 0 20px 60px rgba(0, 0, 0, .38), 0 2px 8px rgba(0, 0, 0, .2);
  padding: 22px 24px 18px;
  transform: translateY(10px) scale(.97);
  opacity: 0;
  transition: transform .22s cubic-bezier(.32, .72, 0, 1), opacity .18s ease;
}
.modal-back.in .modal { transform: none; opacity: 1; }

.modal-title {
  margin: 0 0 8px;
  font-size: 16px;
  font-weight: 600;
  letter-spacing: -0.01em;
  line-height: 1.35;
}
.modal-body {
  margin: 0 0 4px;
  font-size: 13.5px;
  color: var(--text-secondary);
  line-height: 1.55;
}
.modal-label {
  display: block;
  margin: 14px 0 6px;
  font-size: 11px;
  font-weight: 600;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: .07em;
}
.modal-field {
  width: 100%;
  margin-top: 12px;
  background: var(--plane);
  color: var(--text-primary);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 9px 11px;
  font: inherit;
  font-size: 14px;
  resize: vertical;
}
.modal-label + .modal-field { margin-top: 0; }
.modal-field:focus { outline: 2px solid var(--gold-ui); outline-offset: -1px; }
.modal-field::placeholder { color: var(--text-muted); }

.modal-actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  margin-top: 20px;
}
.modal-actions .btn { padding: 8px 15px; }

.btn.danger {
  background: var(--danger-bg);
  border-color: var(--danger-bg);
  color: #fff;
}
.btn.danger:hover { filter: brightness(.9); color: #fff; }

@media (prefers-reduced-motion: reduce) {
  .modal-back, .modal { transition: none !important; }
  .modal { transform: none; opacity: 1; }
}

@media (max-width: 620px) {
  .brand .ar { display: none; }   /* the mark already says العالمية */
}
