/* Alamly Academy — v2 design system (2026-08-16 redesign, LOCKED with Alam).
   Warm paper + two-tone lime + Fraunces/Figtree. See PLAN.md "LOCKED design system".

   NOT loaded by the old 34 pages (they use styles.css / the old indigo system).
   A page uses ONE of the two stylesheets, never both. Pages migrate here one at a time.

   Two-tone lime rule (read this before touching any color here):
   - --lime (bright) is a FILL color only — buttons, chips, highlights. Always paired with
     --ink text/icons on top (max contrast). Never used as text on paper.
   - --lime-text (deep) is a TEXT color only — links, active nav, the "ly" in the logo.
     Never used as a large fill; on paper it is the only lime that is readable as text.
   - On near-black surfaces only, bright --lime MAY be used as text (dark bg flips the rule). */

/* ============================================================================
   ARCHITECTURE — read this before adding ANY rule.
   Layer order in this file: (1) tokens  (2) base / element defaults  (3) reusable
   components  (4) page-layout compositions  (5) responsive. Put a new rule in the
   layer it belongs to, never scattered. Style-guide-only scaffold (.sg-*) lives in
   its OWN file, styleguide.css, loaded only by styleguide.html — not here.

   TWO LAWS. These are what stop this file from rotting back into duplication:

   1. ONE THING = ONE CLASS, DEFINED ONCE. "One thing" means one visual concept,
      not one HTML element. A button is one thing: .btn defines it, .btn-primary is
      a MODIFIER class on the same element (class="btn btn-primary"). Two classes on
      one element is correct. What is NOT allowed: a second class that re-declares
      something the base already owns. A topic-card and a quote-card are different
      CONTENT but share the one card skeleton (.card) — they must not each redraw a
      border / radius / background.

   2. A PAGE OR CONTEXT TWEAK = PARENT SELECTOR + THE SAME CLASS, never a new class,
      never inline style="". Example: .footer .brand-sub { ... } re-colors the brand
      inside the footer without inventing a new class. If you are about to type
      style="..." on an element, stop — it belongs here as a scoped rule instead.
   ============================================================================ */

/* ---------------- fonts ---------------- */
@import url('https://fonts.googleapis.com/css2?family=Fraunces:opsz,wght@9..144,400;9..144,500;9..144,600;9..144,700&family=Figtree:wght@400;500;600;700;800&display=swap');

/* ---------------- tokens ---------------- */
:root {
  --paper:    #faf9f6;
  --paper-2:  #f2f0e9;   /* alt-section tint */
  --ink:      #1a1a1a;
  --ink-2:    #4a4a48;
  --ink-3:    #8a8a86;
  --line:     #e7e5df;
  --line-2:   #d8d5cd;

  --lime:       #d5fc28;  /* FILL only */
  --lime-hover: #c3e922;
  --lime-text:  #577609;  /* TEXT only, on paper. 4.99:1 vs paper (WCAG AA), same green as the fill */
  --lime-wash:  #eaff8c;

  --money:     #1a1a1a;   /* enroll / pay / checkout — the only ink-solid button */
  --money-hover:#000000;
  --money-ink: #ffffff;
  --surface:   #ffffff;   /* card / nav / modal / sidebar bg — always pure white, distinct from --paper */

  /* semantic system feedback — distinct from brand lime, used for status only.
     Two-tone like lime: the plain token is text-safe (AA, 4.5:1+ on paper/white),
     the -vivid token is for icons/large fills only (3:1 threshold, genuinely bright). */
  --ok:      #15803d; --ok-vivid:  #16a34a; --ok-wash:  #e3f6ea;
  --warn:    #b45309; --warn-vivid:#d97706; --warn-wash: #fdf0d9;
  --err:     #dc2626; --err-wash:  #fdeaea;
  --info:    var(--lime-text); --info-wash: var(--lime-wash);

  --font-serif: "Fraunces", Georgia, serif;
  --font-sans:  "Figtree", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;

  /* TYPE SCALE — the only UI/body font-sizes (headings keep the h1/h2/h3 rules + display rems).
     Replaces the ~30 hand-picked sizes (incl. half-pixels like 12.5/13.5/15.5) with one ladder.
     A consistency pass snaps each old size to its nearest step here; nothing shifts more than ~0.5px. */
  --text-xs:   12px;   /* tiny uppercase labels */
  --text-sm:   13px;   /* chips (pill/tag), small meta */
  --text-md:   14px;   /* secondary meta */
  --text-base: 15px;   /* card body / descriptions */
  --text-lg:   16px;   /* standard body in components */
  --text-xl:   18px;   /* lead-ish / large body */

  --radius-sm: 8px;
  --radius:    12px;
  --radius-lg: 18px;
  --radius-pill: 999px;
  --shadow-sm: 0 6px 22px rgba(26,26,26,.06);
  --shadow-md: 0 10px 32px rgba(26,26,26,.09);

  --cap: 1600px;
  --nav-h: 78px;
  /* the one shared width for a centered narrative block (reframe statements, the closing band,
     an oversized pull-statement) — every such section uses this, never its own number. Left-
     aligned wide-paragraph contexts (.measure-lg) are a different, deliberately separate case. */
  --measure: 900px;
  --measure-wide: 1100px;  /* wider centered measure for section heads that sit over full-width content */

  /* SPACING SCALE — the only spacing values allowed. Every gap, margin, and section padding
     resolves to one of these, so spacing is a system, never a guessed one-off number. 8px base. */
  --sp-0: 0px;
  --sp-1: 8px;
  --sp-2: 16px;
  --sp-3: 24px;
  --sp-4: 32px;
  --sp-5: 48px;
  --sp-6: 64px;
  --sp-7: 96px;
  /* half-steps on the 4px grid — the common in-between gaps (4/12/20/40) that were previously
     raw px. With these, the whole spacing system is 4/8/12/16/20/24/32/40/48/64/96; off-grid
     one-offs (10/14/18/26/30/36…) snap to the nearest of these during the consistency pass. */
  --sp-05: 4px;  --sp-15: 12px;  --sp-25: 20px;  --sp-45: 40px;

  /* Section rhythm: fixed vertical padding for every top-level page section (top AND bottom),
     so every public page breathes identically. 80px = 8px base x 10. One value, used everywhere. */
  --section-y: 80px;

  /* STRUCTURAL WIDTHS — the repeated layout dimensions, named so pages stop inventing magic
     numbers. Rails are parameterized: a page sets --rail-w on .with-rail for its own width. */
  --w-card:   460px;  /* a focused single card: sign-in / sign-up / verify / modal */
  --w-narrow: 720px;  /* single-column reading width: account pages, legal body */
  --rail-w:   410px;  /* default sidebar/rail width for .with-rail (course/resource/event detail cards) */
}

/* ---------------- base ---------------- */
* { box-sizing: border-box; margin: 0; padding: 0; }
/* NOTE: do not add overflow-x:hidden here. It forces overflow-y to compute as `auto` on both
   html and body (CSS overflow-x/y coupling), creating two nested scroll containers, which is
   the classic silent way position:sticky breaks (sidebar nav, sticky enroll box, course player
   sidebar, etc.). Real horizontal-overflow causes get fixed at the source (grid minmax(0,1fr)
   guards, button white-space) instead. */
html { scroll-behavior: smooth; scroll-padding-top: 96px; -webkit-text-size-adjust: 100%; }
body { font-family: var(--font-sans); color: var(--ink-2); background: var(--paper);
  font-size: 18px; line-height: 1.7; -webkit-font-smoothing: antialiased; }
img, svg { max-width: 100%; display: block; }
a { color: var(--lime-text); text-decoration: none; }
a:hover { text-decoration: underline; text-underline-offset: 3px; }
/* every heading gets breathing room below it by default — components override this only when
   they have a real reason (documented at the override), never by accident. This is what used to
   be missing: each component invented its own margin-bottom (4/6/8/10/16/22px) instead of one
   heading ever having a sane default. */
h1,h2,h3,h4 { font-family: var(--font-serif); color: var(--ink); font-weight: 600; letter-spacing: -.015em;
  line-height: 1.08; margin-bottom: 16px; }
h1 { font-size: clamp(2.2rem, 4.2vw, 3.4rem); font-weight: 600; margin-bottom: 24px; }
h2 { font-size: clamp(1.7rem, 2.8vw, 2.25rem); line-height: 1.5; margin-bottom: 20px; }
h3 { font-size: 1.5rem; letter-spacing: -.01em; line-height: 1.25; margin-bottom: 8px; }
h4 { font-size: 1.125rem; line-height: 1.3; margin-bottom: 8px; }
p { color: var(--ink-2); font-size: 17px; }
strong { color: var(--ink); font-weight: 600; }
code { font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace; font-size: .9em;
  background: var(--paper-2); padding: 2px 6px; border-radius: 5px; color: var(--ink); }

.wrap { width: 90%; max-width: var(--cap); margin: 0 auto; }
@media (min-width: 1600px) { .wrap { width: 80%; } }
/* footer stays at 90% even on very wide screens — deliberately exempt from the 80% shrink,
   nothing else should be. Higher specificity than plain .wrap wins regardless of media query. */
.footer .wrap { width: 90%; }
/* ---- section: the one vertical-rhythm block every page is built from ---- */
.section { padding: var(--section-y) 0; }
.section.tight { padding: var(--section-y) 0; }
/* Section rhythm (public pages): the <section>s inside the public <main class="site-main"> auto-alternate
   paper / paper-2, so conditional or reordered sections never double up a background (no more manual `tint`
   juggling). Scoped to .site-main only, so app (.portal-main) and admin (.admin-main) shells are untouched
   even once they are <main> too; the <header>/<footer>/modals live OUTSIDE <main>, so nth-of-type counts
   only real content sections. The :nth-of-type test is wrapped in :where() to keep this rule LOW specificity
   (0,1,1), so the plain 2-class .tint / .plain overrides below win on their own, no !important, no ordering
   tricks needed. */
.site-main > section:where(:nth-of-type(odd)) { background: var(--paper); }
.site-main > section:where(:nth-of-type(even)) { background: var(--paper-2); }
/* Explicit background overrides — placed AFTER the alternation. Add `.tint` to force paper-2 (grey) or
   `.plain` to force paper (white) on any section, regardless of its odd/even position above. */
.section.tint { background: var(--paper-2); }
.section.plain { background: var(--paper); }
.section-head { margin-bottom: var(--sp-2); }
.section-head h2 { margin-bottom: 0; }
/* the centered variant of a section head — was previously done ad hoc with inline
   style="text-align:center" wherever needed, which is exactly how the testimonials heading
   ended up inconsistent with everything else. Always use this class instead. */
.section-head.center { text-align: center; max-width: var(--measure-wide); margin-left: auto; margin-right: auto; }
/* Centered section intros stay at a readable line length even though the heading can be wide — this is
   what keeps the "center-aligned page" convention from producing hard-to-read full-width paragraphs. */
.section-head.center .lead, .section-head.center .prose { max-width: 62ch; margin-left: auto; margin-right: auto; }
/* the same centering, for a standalone heading that isn't inside a full .section-head block
   (so it doesn't also inherit .section-head's own bottom margin) */
.center-measure { max-width: var(--measure-wide); margin-left: auto; margin-right: auto; text-align: center; }
/* Centered narrative column spacing (locked with Alam): even 20px gap between stacked children,
   the first child gets 25px below and no top, the last child gets no margin (so no trailing gap).
   CANON (2026-09-20): a section intro is ONE .center-measure holding the heading + its lead(s),
   built exactly like the hero. It replaces the old "section-head.center (title) then a separate
   center-measure (text)" split. Body blocks (grid/stats/steps/faq-list…) follow the intro as siblings. */
.center-measure > :not(:last-child) { margin-bottom: 20px !important; }
.center-measure > :first-child { margin-bottom: 25px !important; margin-top: 0 !important; padding-top: 0 !important; padding-bottom: 0 !important; }
.center-measure > :last-child { margin-top: 0 !important; margin-bottom: 0 !important; padding-top: 0 !important; padding-bottom: 0 !important; }
/* Gap DOWN to the body that follows an intro, and only when a body follows — a hero (a .center-measure
   with nothing after it) keeps a zero trailing gap. This is what lets the intro double as the section head. */
.center-measure:not(:last-child) { margin-bottom: var(--sp-45); }

/* ---- skeleton / layout primitives ----
   The reusable STRUCTURE every page is composed from, so two pages built by different hands
   still breathe identically. Atoms (buttons, cards) come from the components layer; these are
   the bones that arrange and space them. One canonical way to build each structural thing:
     .section          one vertical-rhythm block (padding). + .tight / .tint. (above)
     .section-head     the title+lead cluster atop a section (left). + .center for centered.
     .center-measure   the ONE way to build a centered narrative column (max var(--measure)).
     .grid.cols-N      the ONE equal-column responsive grid (N = 2 / 3 / 4), gap from the scale.
     .frame            the ONE framed-media container (hairline + radius + top-anchored crop). */
.grid { display: grid; gap: var(--sp-3); }
.grid + .grid { margin-top: var(--sp-4); }  /* e.g. flagship row above the normal card grid */
.res-featured { margin-bottom: var(--sp-6); }  /* the flagship "picks" band above the filter bar */

/* ---- Masters admin: uses the shared two-pane admin shell (.adm-split / .adm-rail / .adm-detail,
   documented in the "Admin two-pane shell" section). The values panel is the only Masters-specific
   wrapper still needed; the old .masters-head/.masters-grid/.masters-nav layout was retired. ---- */
.masters-panel { min-width: 0; }

/* value rows — a grid so the columns line up; first row flush at the top, last row loses its divider.
   Row inputs/selects reuse the shared .field/.repeat-row control styling (Masters is added to those
   rules, see the form section); action buttons are plain .btn. No Masters-only control styles. */
/* flex (not grid) so a narrow detail pane wraps the action buttons to a second line instead of
   overflowing horizontally. The icon-select is fixed, the label grows, the actions wrap when tight. */
.master-row { display: flex; flex-wrap: wrap; align-items: center; column-gap: 10px; row-gap: 10px; padding: 18px 0; border-bottom: 1px solid var(--line); }
.master-row:first-child { padding-top: 6px; }
.master-row:last-child { border-bottom: none; padding-bottom: 4px; }
.master-row.off { opacity: .55; }
.master-row > select { flex: 0 0 128px; }
.master-row > input[type="text"] { flex: 1 1 200px; min-width: 150px; }
.master-ic { display: inline-grid; place-items: center; color: var(--lime-text); flex: none; }
.master-ic svg { width: 20px; height: 20px; }
.master-slug { font-size: 12.5px; color: var(--ink-3); font-weight: 600; white-space: nowrap; flex: none; }
.master-acts { display: flex; align-items: center; gap: 8px; justify-content: flex-end; flex: 1 0 auto; margin-left: auto; }
.master-add { display: flex; flex-wrap: wrap; align-items: center; column-gap: 10px; row-gap: 10px; margin-top: 22px; padding-top: 20px; border-top: 1px solid var(--line); }
.master-add > select { flex: 0 0 128px; }
.master-add > input[type="text"] { flex: 1 1 220px; min-width: 160px; }
.master-add > button { flex: none; }
/* every control in a master row shares ONE height (inputs/selects were taller than the buttons) */
.master-row input[type="text"], .master-row select, .master-add input[type="text"], .master-add select,
.master-row input[type="url"], .master-add input[type="url"] { height: 44px; padding-top: 0; padding-bottom: 0; }
.master-url { flex: 1 1 200px; min-width: 140px; }

/* ---- Instructor picker (course editor): avatar + name cards, single-select via :has (no JS). In view
   mode only the chosen one shows. Instructors are a reusable entity (bak34759in/instructors.php). ---- */
.pick-grid { display: flex; flex-wrap: wrap; gap: 10px; }
.pick-card { display: flex; align-items: center; gap: 11px; border: 1px solid var(--line-2); border-radius: var(--radius); padding: 8px 16px 8px 8px; cursor: pointer; background: var(--surface); position: relative; }
.pick-card:hover { border-color: var(--ink-2); }
.pick-card input { position: absolute; opacity: 0; width: 0; height: 0; }
.pick-card:has(input:checked) { border-color: var(--ink); box-shadow: inset 0 0 0 1px var(--ink); }
.pick-card .pick-av { width: 40px; height: 40px; border-radius: 50%; overflow: hidden; flex: none; background: var(--paper-2); display: grid; place-items: center; color: var(--ink-3); }
.pick-card .pick-av img { width: 100%; height: 100%; object-fit: cover; }
.pick-card .pick-av svg { width: 20px; height: 20px; }
.pick-card .pick-av.pick-none { font-weight: 700; color: var(--ink-3); }
.pick-card .pick-name { font-size: 14px; font-weight: 600; display: flex; flex-direction: column; line-height: 1.35; }
.pick-card .pick-name small { font-weight: 400; color: var(--ink-3); font-size: 12px; }
.adm-detail:not(.is-editing) .pick-grid { pointer-events: none; }
.adm-detail:not(.is-editing) .pick-card:not(:has(input:checked)) { display: none; }   /* view mode: show only the chosen instructor */
.master-row .btn, .master-add .btn { height: 44px; }
.master-row .btn-icon, .master-add .btn-icon { width: 44px; padding: 0; justify-content: center; }
.master-row > .chip-swatch, .master-add > .chip-swatch { align-self: center; }
/* unsaved-changes cue: left lime accent on a changed row, and its Save/Add button turns primary */
.master-row.is-dirty { box-shadow: inset 3px 0 0 var(--lime); }
.master-row.is-dirty [value="save"], .master-add.is-dirty [value="add"] { background: var(--lime); border-color: var(--lime); color: var(--ink); }
.master-empty { padding: 14px 0; }
@media (max-width: 820px) {
  /* rows are flex + flex-wrap, so they already stack on their own; only the actions need nudging */
  .master-acts { justify-content: flex-start; flex-wrap: wrap; }
}
.grid.cols-2 { grid-template-columns: repeat(2, minmax(0,1fr)); }
.grid.cols-3 { grid-template-columns: repeat(3, minmax(0,1fr)); }
.grid.cols-4 { grid-template-columns: repeat(4, minmax(0,1fr)); }
@media (max-width: 960px) { .grid.cols-3, .grid.cols-4 { grid-template-columns: repeat(2, minmax(0,1fr)); } }
@media (max-width: 560px) { .grid.cols-2, .grid.cols-3, .grid.cols-4 { grid-template-columns: 1fr; } }
/* Centered card row (home "latest" strips): up to 3 cards, but 1 or 2 sit CENTERED, not left-aligned
   the way a fixed 3-col grid would leave them. Card basis mirrors .grid.cols-3 (thirds, same gap). */
.card-row { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--sp-3); }
.card-row > * { flex: 0 1 calc((100% - 2 * var(--sp-3)) / 3); }
@media (max-width: 960px) { .card-row > * { flex-basis: calc((100% - var(--sp-3)) / 2); } }
@media (max-width: 560px) { .card-row > * { flex-basis: 100%; } }

.frame { border: 1px solid var(--line); border-radius: var(--radius-lg); overflow: hidden; background: var(--paper-2); }
.frame img { width: 100%; height: 100%; object-fit: cover; object-position: top; display: block; }
.frame.ratio-portrait { aspect-ratio: 4/5; }
.frame.ratio-video { aspect-ratio: 16/9; }
.frame.ratio-wide { aspect-ratio: 16/10; }

/* content + sticky rail — the ONE way to build a two-column page with a sidebar (course-player
   curriculum, checkout summary, legal nav all become this). One grid, a parameterized rail width
   (--rail-w, set per page), a sticky rail, collapsing to one column on small screens. The rail
   element carries .rail so it sticks; add .rail-right to place the rail after the content. */
.with-rail { display: grid; grid-template-columns: var(--rail-w) minmax(0, 1fr); gap: var(--sp-5); align-items: start; }
.with-rail.rail-right { grid-template-columns: minmax(0, 1fr) var(--rail-w); }
/* the sticky rail is the GRID ITEM itself (with align-self:start from the parent), so it has the
   full tall grid cell to stick within — a sticky CHILD of a start-aligned item can't move. */
.with-rail > .rail, .with-rail > aside { position: sticky; top: calc(var(--nav-h) + var(--sp-3)); align-self: start; }
@media (max-width: 960px) {
  .with-rail, .with-rail.rail-right { grid-template-columns: 1fr; }
  .with-rail > .rail { position: static; }
}

/* center a bounded card in the viewport — the ONE way to build a focused single-card screen
   (sign-in, sign-up, verify, reset, forgot). The card inside is capped at --w-card. */
.center-screen { min-height: calc(100vh - var(--nav-h)); display: grid; place-items: center;
  padding: var(--sp-5) var(--sp-3); }
.center-screen > * { width: 100%; max-width: var(--w-card); }
.lead { font-size: clamp(1.125rem, 1.4vw, 1.25rem); line-height: 1.55; color: var(--ink-2); }
.sub  { font-size: 15.5px; line-height: 1.55; color: var(--ink-3); }
.small { font-size: 13.5px; line-height: 1.6; color: var(--ink-3); }
.muted { color: var(--ink-3); }
/* hand-drawn highlight: a rough sketchy lime underline instead of a straight bar. The ::after squiggle
   (an SVG stretched to the box, not a background squeezed onto the text) makes thickness = box height,
   and that height is FONT-SIZE-RELATIVE (em) with a floor and ceiling. So a plain <span class="hl">
   works in ANY context and scales ITSELF: thick under a hero h1, thinner in body copy, no per-instance
   math and no per-context override needed. Emphasis inside a testimonial quote (<em>) reuses the very
   same swipe — that is how the endorsement quotes read their highlighted words.
   To tune globally, change the one clamp below (min / factor / max). */
.hl, .t-quote em {
  font-style: normal;
  /* The swipe is an inline BACKGROUND (not an ::after box), with box-decoration-break: clone, so it
     follows the text across line breaks AUTOMATICALLY — every wrapped line gets its own swipe, no
     per-word spans, no z-index tricks (a background always sits behind the letters). Thickness is
     font-size-relative (em) with a floor + ceiling, so a plain <span class="hl"> scales itself
     anywhere: thick under a hero, thin in body. To tune globally, change the one clamp below. */
  -webkit-box-decoration-break: clone; box-decoration-break: clone;
  padding: 0 0.12em;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 20' preserveAspectRatio='none'%3E%3Cpath d='M3,12 C20,5 34,17 54,9 C74,3 90,16 110,8 C130,2 147,15 167,7 C181,3 190,10 197,8' fill='none' stroke='%23c3e922' stroke-width='6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: 0 100%;
  background-size: 100% clamp(8px, 0.34em, 24px);
}
/* Highlight colour locked to lime-hover (#c3e922) on 2026-08-26 (chosen from _preview-highlight). */

/* ---------------- buttons ---------------- */
.btn { display: inline-flex; align-items: center; gap: var(--sp-15); font-family: var(--font-sans); font-size: var(--text-lg);
  font-weight: 600; line-height: 1; cursor: pointer; padding: var(--sp-2) var(--sp-3); border-radius: var(--radius-sm);
  border: 1.5px solid transparent; transition: background .15s, opacity .15s;
  white-space: nowrap; }
/* buttons never change text color or gain underline on hover — background only, always */
.btn:hover, .btn:focus-visible { text-decoration: none; }
/* descendant selector, not a class, so a forgotten class="ic" can't silently break icon sizing */
.btn svg { width: 18px; height: 18px; flex: none; }
.btn-lg { padding: var(--sp-25) var(--sp-4); font-size: var(--text-xl); }
.btn-lg svg { width: 20px; height: 20px; }
.btn-sm { padding: var(--sp-1) var(--sp-2); font-size: var(--text-md); }
.btn-sm svg { width: 16px; height: 16px; }
.btn-block { width: 100%; justify-content: center; }
.btn-row { display: flex; gap: var(--sp-2); flex-wrap: wrap; align-items: center; }
/* centered button row — for heroes and section intros (replaces inline style="justify-content:center") */
.btn-row.center { justify-content: center; }

.btn-primary { background: var(--lime); color: var(--ink); }
.btn-primary:hover { background: var(--lime-hover); }
.btn-money { background: var(--money); color: var(--money-ink); }
.btn-money:hover { background: var(--money-hover); }
.btn-line { background: var(--surface); color: var(--ink); border-color: var(--line-2); }
.btn-line:hover { background: var(--paper-2); }
.btn-ghost { background: none; color: var(--lime-text); padding-left: var(--sp-05); padding-right: var(--sp-05); }
.btn-ghost:hover { background: var(--lime-wash); }
.btn-danger { background: transparent; color: var(--err); border-color: var(--line-2); }
.btn-danger:hover { background: var(--err-wash); }
.btn[disabled], .btn.is-disabled { opacity: .45; cursor: not-allowed; pointer-events: none; }
.btn-icon { padding: var(--sp-15); border-radius: var(--radius-sm); }
.btn-icon svg { margin: 0; }

/* ---------------- forms ---------------- */
.field { margin-bottom: var(--sp-25); text-align: left; }
.field label { display: block; font-size: var(--text-md); font-weight: 600; color: var(--ink); margin-bottom: var(--sp-1); }
.field label .req { color: var(--err); margin-left: 2px; }
.field .lbl-row { display: flex; justify-content: space-between; align-items: baseline; }
.field input, .field textarea, .field select { width: 100%; border: 1.5px solid var(--line-2);
  border-radius: var(--radius-sm); padding: var(--sp-15) var(--sp-2); font-size: var(--text-lg); font-family: inherit;
  color: var(--ink); background: var(--surface); transition: border-color .15s, box-shadow .15s; }
.field textarea { resize: vertical; min-height: 110px; }
.field select, .repeat-row select, .res-fileitem select, .master-row select, .master-add select { appearance: none; padding-right: 42px; cursor: pointer;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%234a4a48' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 14px center; background-size: 16px; }
.field input:focus, .field textarea:focus, .field select:focus { outline: none; border-color: var(--ink);
  box-shadow: 0 0 0 3px var(--lime-wash); }
.field .hint { font-size: var(--text-sm); color: var(--ink-3); margin-top: var(--sp-1); }
.otp-input { text-align: center; letter-spacing: .4em; font-size: 1.3rem; }   /* single-box 6-digit code field */
.field.bad input, .field.bad textarea, .field.bad select { border-color: var(--err); }
.field .field-err { display: flex; align-items: center; gap: var(--sp-1); color: var(--err); font-size: var(--text-sm); font-weight: 600; margin-top: var(--sp-1); }
.field .field-err svg { width: 14px; height: 14px; flex: none; }
.field.ok input { border-color: var(--ok); }
.field .field-ok { display: flex; align-items: center; gap: var(--sp-1); color: var(--ok); font-size: var(--text-sm); font-weight: 600; margin-top: var(--sp-1); }
.field .field-ok svg { width: 14px; height: 14px; flex: none; }
.checkrow { display: flex; align-items: flex-start; gap: 10px; font-size: 14.5px; color: var(--ink-2); margin-bottom: 18px; text-align: left; }
.checkrow input { margin-top: 4px; flex: none; accent-color: var(--lime); }
.checkrow.bad { color: var(--err); }
.field input[type="checkbox"], .field input[type="radio"] { width: auto; accent-color: var(--lime); }

/* ---- password field UX: show/hide toggle (every password input) + live requirements checklist ---- */
.pw-wrap { position: relative; display: block; }
.pw-wrap input { width: 100%; padding-right: 46px; }
.pw-toggle { position: absolute; top: 50%; right: 8px; transform: translateY(-50%); display: grid; place-items: center;
  width: 32px; height: 32px; padding: 0; border: none; background: none; color: var(--ink-3); cursor: pointer; border-radius: 7px; }
.pw-toggle:hover { color: var(--ink); background: var(--paper-2); }
.pw-toggle svg { width: 19px; height: 19px; }
.pw-check { display: grid; gap: 7px; margin-top: 10px; padding: 12px 14px; background: var(--paper-2); border-radius: var(--radius-sm); }
.pw-req { display: flex; align-items: center; gap: 9px; font-size: var(--text-sm); color: var(--ink-3); }
.pw-req .pw-dot { flex: none; display: grid; place-items: center; width: 18px; height: 18px; border-radius: 50%;
  background: var(--surface); border: 1.5px solid var(--line-2); color: transparent; transition: background .12s, color .12s, border-color .12s; }
.pw-req .pw-dot svg { width: 12px; height: 12px; }
.pw-req.ok { color: var(--ink-2); }
.pw-req.ok .pw-dot { background: var(--lime); border-color: var(--lime); color: var(--ink); }

/* ---- active-sessions list (security page) + multi-device notice bar ---- */
.sess-list { display: grid; gap: 10px; margin-top: 12px; }
.sess-item { display: flex; align-items: center; gap: 14px; padding: 14px 16px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); }
.sess-item.is-current { border-color: var(--lime); background: var(--lime-wash); }
.sess-item .c { flex: none; display: grid; place-items: center; }
.sess-item .c svg { width: 22px; height: 22px; color: var(--ink-3); }
.sess-main { flex: 1; min-width: 0; display: grid; gap: 2px; }
.sess-item .sess-act { flex: none; }
.sess-you { font-size: var(--text-xs); font-weight: 700; color: var(--lime-text); background: var(--surface); border: 1px solid var(--lime); border-radius: var(--radius-pill); padding: 1px 8px; margin-left: 6px; }
.md-notice { display: flex; align-items: center; gap: 14px; padding: 10px 20px; background: var(--warn-wash); color: var(--warn); border-bottom: 1px solid var(--warn); font-size: var(--text-sm); font-weight: 600; }
/* the display:flex above would otherwise beat the browser's built-in [hidden]=display:none, leaving the
   bar visible when it should be hidden (and un-closable) — so restore hidden explicitly. */
.md-notice[hidden] { display: none; }
.md-notice .md-txt { flex: 1; min-width: 0; }
.md-notice a { color: var(--warn); text-decoration: underline; white-space: nowrap; }

/* ---- tabs (account Security, and future settings surfaces). Tabs are anchors (?tab=…) so they work
   without JS; main.js intercepts the click to switch panels in place. Add a new tab = one <a> + one
   .tab-panel, nothing else. ---- */
.tabs { display: flex; flex-wrap: wrap; gap: 2px; border-bottom: 1px solid var(--line); margin-bottom: var(--sp-4); }
.tab { display: inline-flex; align-items: center; gap: 8px; padding: 12px 16px; margin-bottom: -1px; border: none; background: none;
  font: inherit; font-weight: 600; color: var(--ink-3); text-decoration: none; cursor: pointer; border-bottom: 2px solid transparent; }
.tab:hover { color: var(--ink); }
.tab.on { color: var(--ink); border-bottom-color: var(--lime); }
.tab-badge { font-size: var(--text-xs); font-weight: 700; line-height: 1; color: var(--ink); background: var(--lime); border-radius: var(--radius-pill); padding: 2px 7px; }
.tab-panel { display: none; }
.tab-panel.on { display: block; }
.md-notice .md-x { flex: none; background: none; border: none; color: inherit; cursor: pointer; display: grid; place-items: center; width: 28px; height: 28px; border-radius: 6px; }
.md-notice .md-x:hover { background: rgba(0,0,0,.07); }
.md-notice .md-x svg { width: 18px; height: 18px; }
.form-note { display: none; margin-top: 14px; font-size: 15px; font-weight: 600; color: var(--ok); }
.form-note.bad { color: var(--err); }
.form-note.show { display: block; }                          /* server-rendered note that should show */
.form-note.flash { display: block; margin-bottom: 16px; }    /* a top-of-page flash message */

/* ---- form system (documented in styleguide #forms): consistent groups, states, and controls ----
   Group = a titled section of a form (.set-block + a .set-block h2). Every form gets the SAME group
   rhythm and a divider between groups, so forms stop looking custom/cluttered. */
.set-block { margin-bottom: var(--sp-3); padding-bottom: var(--sp-3); border-bottom: 1px solid var(--line); }
.set-block:last-child { margin-bottom: 0; padding-bottom: 0; border-bottom: none; }
.set-block > .hint { margin-top: -8px; margin-bottom: 16px; }   /* a description line under the group title */
/* disabled + read-only controls */
.field input:disabled, .field textarea:disabled, .field select:disabled,
.field input[readonly], .field textarea[readonly] {
  background: var(--paper-2); color: var(--ink-3); cursor: not-allowed; border-color: var(--line); box-shadow: none; }
.field input[readonly]:focus, .field textarea[readonly]:focus { border-color: var(--line); box-shadow: none; }
/* label -> value display row (read-only detail pages: admin user-view, profile email, receipts...) */
.drow { display: grid; grid-template-columns: 160px minmax(0, 1fr); gap: var(--sp-2); align-items: baseline; padding: var(--sp-15) 0; }
.drow + .drow { border-top: 1px solid var(--line); }
.drow .drow-label { font-size: var(--text-md); font-weight: 600; color: var(--ink-3); }
.drow .drow-value { font-size: var(--text-base); color: var(--ink); min-width: 0; }
.drow-value.is-url { word-break: break-all; }                          /* long lead-source URLs */
.drow-value.is-ua { font-size: var(--text-sm); word-break: break-word; } /* browser user-agent */
@media (max-width: 560px) { .drow { grid-template-columns: 1fr; gap: 4px; } }
/* message-inbox detail (bak34759in/messages.php): the enquiry body + the chat transcript turns */
.msg-body { margin: 0; line-height: 1.7; color: var(--ink-2); white-space: pre-wrap; }
.msg-turn { margin-bottom: var(--sp-2); }
.msg-turn .msg-q { margin: 0 0 3px; font-size: var(--text-md); color: var(--ink-3); }
.msg-turn .msg-a { margin: 0; line-height: 1.6; color: var(--ink); }
/* toggle switch (a styled checkbox) */
.toggle { display: inline-flex; align-items: center; gap: 12px; cursor: pointer; font-size: 14.5px; color: var(--ink-2); }
.toggle input { position: absolute; opacity: 0; width: 0; height: 0; }
.toggle .tg-track { width: 42px; height: 24px; border-radius: 999px; background: var(--line-2); position: relative;
  transition: background .15s; flex: none; }
.toggle .tg-track::after { content: ""; position: absolute; top: 3px; left: 3px; width: 18px; height: 18px;
  border-radius: 50%; background: #fff; box-shadow: 0 1px 3px rgba(0,0,0,.2); transition: transform .15s; }
.toggle input:checked + .tg-track { background: var(--lime); }
.toggle input:checked + .tg-track::after { transform: translateX(18px); }
.toggle input:disabled + .tg-track { opacity: .5; cursor: not-allowed; }
.toggle input:focus-visible + .tg-track { box-shadow: 0 0 0 3px var(--lime-wash); }
/* radio / checkbox group: a titled set of .checkrow options */
.opt-group { display: grid; gap: 10px; }
.code-input { display: flex; gap: 10px; }
.code-input input { width: 52px; height: 60px; text-align: center; font-size: 22px; font-weight: 700;
  font-family: var(--font-sans); border: 1.5px solid var(--line-2); border-radius: var(--radius-sm); }
.code-input input:focus { outline: none; border-color: var(--ink); }

/* ---------------- chips / tags / badges ---------------- */
.pill { display: inline-flex; align-items: center; gap: var(--sp-1); font-size: var(--text-sm); font-weight: 700;
  padding: 7px 14px; border-radius: var(--radius-pill); background: var(--lime-wash); color: var(--lime-text); }
.pill.solid { background: var(--lime); color: var(--ink); }
.pill.neutral { background: var(--paper-2); color: var(--ink-2); }

.tag { display: inline-flex; align-items: center; gap: var(--sp-1); font-size: var(--text-sm); font-weight: 700;
  padding: 4px 11px; border-radius: var(--radius-pill); white-space: nowrap; }
.tag-ok   { background: var(--ok-wash); color: var(--ok); }
.tag-warn { background: var(--warn-wash); color: var(--warn); }
.tag-err  { background: var(--err-wash); color: var(--err); }
.tag-neutral { background: var(--paper-2); color: var(--ink-3); }

.ic-chip { width: 50px; height: 50px; border-radius: var(--radius); display: grid; place-items: center;
  background: var(--lime); color: var(--ink); flex: none; }
.ic-chip svg { width: 24px; height: 24px; }
.ic-chip.soft { background: var(--lime-wash); color: var(--lime-text); }
.ic-chip.round { border-radius: 50%; }
.ic-chip.sm { width: 38px; height: 38px; border-radius: var(--radius-sm); }
.ic-chip.sm svg { width: 18px; height: 18px; }

/* ---------------- cards ---------------- */
/* THE content-card skeleton, declared ONCE. Every generic content card (.card, .topic,
   .startcard, .quote, .notecard) shares surface + hairline + large radius from here and
   nowhere else. Each variant below only declares what genuinely differs: its padding, its
   inner layout, and whether it reacts on hover (interactive cards do, static ones don't).
   To change how every content card looks, edit this one rule. */
.card, .topic, .startcard, .quote, .notecard {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-lg);
}
.card { padding: 30px; transition: border-color .15s, box-shadow .15s; }
.card:hover { border-color: var(--line-2); box-shadow: var(--shadow-sm); }
/* h3 margin-bottom now comes from the base rule (8px) — not redeclared per component */
.card p { font-size: 15.5px; }
.card.horizontal { display: flex; gap: 20px; align-items: flex-start; }
.card-media { border-radius: var(--radius-sm); overflow: hidden; margin: -30px -30px 20px; aspect-ratio: 16/9;
  background: var(--paper-2); }
.card-media img { width: 100%; height: 100%; object-fit: cover; display: block; }
.card-foot { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-top: 20px;
  padding-top: 20px; border-top: 1px solid var(--line); }

.stat-row { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 16px; }
.statcard { border: 1px solid var(--line); border-radius: var(--radius); padding: var(--sp-25) var(--sp-3); background: var(--surface); }
.statcard b { display: block; font-family: var(--font-serif); font-size: 2rem; font-weight: 600; color: var(--ink); }
.statcard span { font-size: var(--text-md); color: var(--ink-3); }
a.statcard { display: block; transition: border-color .15s, box-shadow .15s; }
a.statcard:hover { border-color: var(--ink-3); box-shadow: 0 4px 16px rgba(0,0,0,.05); text-decoration: none; }
.statcard.trend-up b::after { content: ""; }

/* align-items:center so the two shorter side plans sit vertically centered against the taller
   featured plan in the middle, which stands out by being a fixed 700px tall. */
.plans { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--sp-3); align-items: center; }
/* a single centered plan card (replaces NorthStar's inline grid-template-columns/justify-content) */
.plans.solo { grid-template-columns: minmax(0, 540px); justify-content: center; }
.plan { position: relative; border: 1px solid var(--line); border-radius: var(--radius-lg); padding: var(--sp-45) var(--sp-4);
  background: var(--surface); display: flex; flex-direction: column; }
.plan.feature { border-color: var(--ink); background: var(--lime-wash); box-shadow: var(--shadow-md);
  padding: var(--sp-5) var(--sp-45); min-height: 700px; }
.plan .badge { position: absolute; top: -14px; left: 50%; transform: translateX(-50%); background: var(--ink);
  color: var(--lime); font-size: var(--text-xs); font-weight: 700; padding: var(--sp-1) var(--sp-2); border-radius: var(--radius-pill);
  white-space: nowrap; }
.plan .flag { color: var(--lime-text); font-weight: 700; font-size: var(--text-sm); text-transform: uppercase; letter-spacing: .04em; margin-bottom: var(--sp-2); }
.plan h3 { font-size: 1.5rem; }
.plan .price { font-family: var(--font-serif); font-size: 2.4rem; font-weight: 600; color: var(--ink); margin: var(--sp-15) 0 var(--sp-05); }
.plan .price span { font-family: var(--font-sans); font-size: .95rem; font-weight: 500; color: var(--ink-3); }
.plan ul { list-style: none; display: grid; gap: var(--sp-2); margin: var(--sp-3) 0; flex: 1; }
.plan li { display: flex; align-items: flex-start; gap: var(--sp-15); font-size: var(--text-base); color: var(--ink-2); }
.plan li .check { flex: none; width: 20px; height: 20px; margin-top: 1px; border-radius: 6px;
  background: var(--lime-wash); color: var(--lime-text); display: grid; place-items: center; }
.plan.feature li .check { background: var(--lime); }
.plan li .check svg { width: 12px; height: 12px; }
.plan .btn { white-space: normal; text-align: center; }

/* offer / discount plan variant */
.plan.offer { border: 2px dashed var(--warn-vivid); }
.plan .offer-tag { display: inline-flex; align-items: center; gap: var(--sp-1); background: var(--warn-vivid); color: #fff;
  font-size: var(--text-xs); font-weight: 700; padding: var(--sp-05) var(--sp-15); border-radius: var(--radius-pill); margin-bottom: var(--sp-2);
  width: fit-content; white-space: nowrap; }
.plan .offer-tag svg { flex: none; width: 14px; height: 14px; }
.plan .price-row { display: flex; align-items: baseline; gap: var(--sp-15); margin: var(--sp-15) 0 var(--sp-05); }
.plan .price-was { font-family: var(--font-serif); font-size: 1.35rem; color: var(--ink-3); text-decoration: line-through; }
.plan .price-now { font-family: var(--font-serif); font-size: 2.4rem; font-weight: 600; color: var(--ink); }
.plan .offer-deadline { display: flex; align-items: center; gap: var(--sp-1); font-size: var(--text-md); color: var(--warn);
  font-weight: 600; margin: var(--sp-1) 0 var(--sp-2); }
.plan .offer-deadline svg { width: 15px; height: 15px; flex: none; }

/* richer plan cards: a per-tier icon (matches the Compass / Field Guide / Expedition naming), a
   hover lift on the two side plans, and a reassurance line above the CTA so the taller featured
   card doesn't read as empty. All from existing tokens. */
.plan { transition: border-color .15s, box-shadow .15s, transform .15s; }
.plan:not(.feature):hover { border-color: var(--line-2); box-shadow: var(--shadow-sm); transform: translateY(-3px); }
.plan-ic { width: 48px; height: 48px; border-radius: var(--radius); background: var(--lime-wash);
  color: var(--lime-text); display: grid; place-items: center; margin-bottom: 18px; }
.plan-ic svg { width: 24px; height: 24px; }
.plan.feature .plan-ic { background: var(--lime); color: var(--ink); }
.plan-assure { display: flex; align-items: center; gap: 8px; font-size: 13px; color: var(--ink-3);
  padding-top: 16px; margin-top: 4px; border-top: 1px solid var(--line); }
.plan.feature .plan-assure { border-top-color: rgba(26,26,26,.12); }
.plan-assure svg { width: 15px; height: 15px; flex: none; color: var(--lime-text); }

/* ---------------- course components (card, curriculum, player, enroll) ---------------- */
/* Catalog card (courses AND resources share this base). Cover flush on top, a padded .ccard-body below,
   tight type. Whole card is a link — no inner button. Flagship (max two per catalog) is larger + dark +
   HORIZONTAL (cover left, body right). Sizes are deliberately compact (matches the approved preview). */
.ccard { display: flex; flex-direction: column; border: 1px solid var(--line); border-radius: var(--radius-lg);
  background: var(--surface); overflow: hidden; transition: border-color .15s, box-shadow .15s; }
a.ccard { text-decoration: none; color: inherit; }
a.ccard:hover { border-color: var(--line-2); box-shadow: 0 10px 30px rgba(13,15,20,.07); }  /* no lift/jerk */
a.ccard:hover h3 { color: var(--lime-text); }
.card-cover { aspect-ratio: 16 / 9; background: var(--paper-2); overflow: hidden; position: relative; flex: none; }
.card-cover img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.card-cover .res-ph { position: absolute; inset: 0; display: grid; place-items: center; color: var(--ink-3); }
.card-cover .res-ph svg { width: 30px; height: 30px; }
/* cover overlays: availability status (top-left) + free-preview / access flag (top-right). Delivery is
   NOT a status — it sits in the meta row (Live / Cohort / Recorded), separate from availability. */
.card-cover .ccard-status { position: absolute; top: 11px; left: 11px; z-index: 1; }
.card-cover .ccard-free { position: absolute; top: 11px; right: 11px; z-index: 1; font-size: 10px; font-weight: 800;
  letter-spacing: .03em; text-transform: uppercase; color: var(--ink); background: var(--lime); border-radius: var(--radius-pill); padding: 3px 8px; box-shadow: var(--shadow-sm); }
.card-status-pill { display: inline-flex; align-items: center; font-size: 11px; font-weight: 800; letter-spacing: .02em; padding: 4px 9px; border-radius: var(--radius-pill); }
.card-status-pill.soon  { color: #7a4a05; background: #ffe6b8; }
.card-status-pill.owned { color: #0c5c56; background: #cfeee9; }
/* resource access badge (top-right of the cover): Free (lime) / Paid (dark) / Free + Paid */
.card-cover .ccard-access { position: absolute; top: 11px; right: 11px; z-index: 1; font-size: 10px; font-weight: 800;
  letter-spacing: .03em; text-transform: uppercase; border-radius: var(--radius-pill); padding: 3px 8px; box-shadow: var(--shadow-sm); }
.ccard-access.free, .ccard-access.both { color: var(--ink); background: var(--lime); }
.ccard-access.paid { color: #fff; background: #14161d; }
.ccard-body { display: flex; flex-direction: column; flex: 1; padding: var(--sp-25); }
.card-chips { display: flex; gap: var(--sp-1); flex-wrap: wrap; align-items: center; margin-bottom: var(--sp-15); }
/* category chip: master-driven icon + label + a CURATED colour (never free hex). Colour key comes from
   masters.color; the palette below is the on-brand, accessible set to choose from in admin. */
.chip { display: inline-flex; align-items: center; gap: 6px; font-size: var(--text-sm); font-weight: 700; line-height: 1;
  padding: 5px 10px 5px 8px; border-radius: var(--radius-pill); border: 1px solid transparent; color: var(--ink-2); background: var(--paper-2); }
.chip svg { width: 14px; height: 14px; }
.chip.c-lime  { color: #3f5406; background: #eaf7c6; }
.chip.c-teal  { color: #0c5c56; background: #d6f3ee; }
.chip.c-plum  { color: #6b2d6b; background: #f4e2f4; }
.chip.c-sky   { color: #1e4f7a; background: #dbecfb; }
.chip.c-amber { color: #7a4a05; background: #ffedcc; }
.chip.c-rose  { color: #8a2b47; background: #fbdfe8; }
.chip.c-slate { color: #33415a; background: #e2e8f2; }
/* admin masters: a small swatch showing the chosen chip colour */
.chip-swatch { display: inline-block; width: 16px; height: 16px; border-radius: 50%; flex: none; border: 1px solid var(--line-2); background: var(--paper-2); }
.chip-swatch.c-lime { background: #eaf7c6; } .chip-swatch.c-teal { background: #d6f3ee; } .chip-swatch.c-plum { background: #f4e2f4; }
.chip-swatch.c-sky { background: #dbecfb; } .chip-swatch.c-amber { background: #ffedcc; } .chip-swatch.c-rose { background: #fbdfe8; } .chip-swatch.c-slate { background: #e2e8f2; }
.ccard h3 { font-size: 1.12rem; line-height: 1.28; margin: 0 0 var(--sp-1); }
.ccard .desc { font-size: var(--text-md); color: var(--ink-2); line-height: 1.5; margin: 0 0 var(--sp-2); }
.ccard .desc.clamp2 { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.ccard .meta-row { margin-top: auto; gap: var(--sp-1) var(--sp-25); font-size: var(--text-sm); }
.ccard .meta-item .c svg { width: 15px; height: 15px; }
.ccard-foot { display: flex; align-items: center; gap: var(--sp-2); margin-top: var(--sp-2); padding-top: var(--sp-2); border-top: 1px solid var(--line); }
.ccard-price { font-size: var(--text-lg); font-weight: 800; }
.ccard-price.free { color: var(--lime-text); }
.ccard-view { display: inline-flex; align-items: center; gap: 5px; font-size: 13px; font-weight: 700; color: var(--lime-text); margin-left: auto; }
.ccard-view svg { width: 15px; height: 15px; }
/* flagship: larger, dark, horizontal (cover left | body right) */
.ccard.flagship { display: grid; grid-template-columns: 42% 1fr; min-height: 380px; background: #14161d; border-color: #262933; color: #cfcfc8; }
.ccard.flagship .card-cover { aspect-ratio: auto; height: 100%; min-height: 380px; }
.ccard.flagship .ccard-body { justify-content: center; padding: var(--sp-4); }
.ccard.flagship h3 { color: #fff; font-size: 1.5rem; }
.ccard.flagship .desc { color: rgba(255,255,255,.7); }
.ccard.flagship .meta-item b { color: #cfcfc8; }
.ccard.flagship .meta-item .c { color: #8a8a82; }
.ccard.flagship .pill.neutral { background: rgba(255,255,255,.12); color: #e8e8e4; }
.ccard.flagship .ccard-view { color: var(--lime); }
.ccard.flagship .ccard-foot { border-top-color: rgba(255,255,255,.14); }
a.ccard.flagship:hover { border-color: #3d4150; box-shadow: 0 14px 40px rgba(0,0,0,.25); }
a.ccard.flagship:hover h3 { color: var(--lime); }
@media (max-width: 700px) { .ccard.flagship { grid-template-columns: 1fr; } .ccard.flagship .card-cover { aspect-ratio: 16/9; height: auto; min-height: 0; } }

/* standalone price component — was MISSING entirely, which is why prices read as invisible
   plain body text wherever they weren't nested inside .plan. Same look everywhere it's used
   (course card foot, sticky enroll box): bold serif, unmistakably the most important number
   on the card. */
.price { font-family: var(--font-serif); font-size: 1.7rem; font-weight: 600; color: var(--ink);
  letter-spacing: -.01em; }
.price small { font-family: var(--font-sans); font-size: .85rem; font-weight: 500; color: var(--ink-3); }

/* inline meta row: duration, lesson count, level — supporting metadata, NOT a primary action.
   Per the hierarchy rules: neutral only, no lime. Icon inherits ink-3, no chip/circle background.
   Reserve lime for the one thing on the card actually competing for attention. */
.meta-row { display: flex; gap: var(--sp-2) var(--sp-3); flex-wrap: wrap; margin: var(--sp-2) 0; }
.meta-item { display: flex; align-items: center; gap: var(--sp-1); font-size: var(--text-md); color: var(--ink-3); }
.meta-item .c { color: var(--ink-3); display: grid; place-items: center; flex: none; }
.meta-item .c svg { width: 17px; height: 17px; }
.meta-item b { color: var(--ink-2); font-weight: 600; }

/* neutral note panel — for supporting/marketing asides that are NOT a system alert.
   Deliberately not lime-wash: a decorative note competing with the real CTA for the eye is
   exactly the "everything is lime" problem the hierarchy rules exist to prevent. */
.panel { border: 1px solid var(--line); border-radius: var(--radius-sm); padding: 14px 16px;
  font-size: 13.5px; color: var(--ink-2); background: var(--paper-2); }

.inst { display: flex; align-items: center; gap: 12px; padding: 12px 14px; border: 1px solid var(--line);
  border-radius: var(--radius); }
.inst .avatar { width: 44px; height: 44px; font-size: 15px; }
.inst b { display: block; font-size: 14px; }
.inst span { font-size: 11.5px; color: var(--ink-3); text-transform: uppercase; letter-spacing: .05em; }

/* checkmark list — reusable: course-detail "what you'll learn", plan perks, anywhere a list of
   claims needs a tick, not just inside .plan */
.check-list { list-style: none; display: grid; gap: 14px; }
/* a centered check-list (inline-grid so it shrink-wraps and centers under a centered intro; replaces
   consulting's inline style="display:inline-grid;text-align:left") */
.check-list.center { display: inline-grid; text-align: left; }
.check-list li { display: flex; align-items: flex-start; gap: 12px; font-size: 15.5px; color: var(--ink-2); }
.check-list .check { flex: none; width: 22px; height: 22px; margin-top: 1px; border-radius: 6px;
  background: var(--lime-wash); color: var(--lime-text); display: grid; place-items: center; }
.check-list .check svg { width: 13px; height: 13px; }
/* hero value list: flow the items horizontally and wrap to the next line when space runs out (chips-style),
   instead of a vertical stack. Used in the detail-page hero under the fact capsules. */
.check-list.hero-list { display: flex; flex-wrap: wrap; gap: 12px 24px; }
.check-list.hero-list li { align-items: center; }

/* curriculum accordion — a serif chapter number carries the editorial feel; lessons are visibly
   indented as children of their chapter (not just a flat list under a divider), with a small dot
   marker continuing the hierarchy down each row. */
.curric details { border: 1px solid var(--line); border-radius: var(--radius-lg); margin-bottom: 12px;
  overflow: hidden; background: var(--surface); transition: border-color .15s; }
.curric details:last-child { margin-bottom: 0; }   /* no dangling gap after the last module */
.curric details[open] { border-color: var(--line-2); }
.curric summary { cursor: pointer; list-style: none; padding: 20px 22px; display: flex; align-items: center;
  gap: 16px; color: var(--ink); transition: background .15s; }
.curric summary:hover { background: var(--paper-2); }
.curric summary::-webkit-details-marker { display: none; }
.curric .num { font-family: var(--font-serif); font-size: 1.3rem; font-weight: 600; color: var(--line-2);
  flex: none; min-width: 32px; transition: color .15s; }
.curric details[open] .num { color: var(--lime-text); }
.curric .ctitle { flex: 1; min-width: 0; font-weight: 600; font-size: 16px; }
.curric summary .n { color: var(--ink-3); font-weight: 500; font-size: 13px; flex: none; }
.curric > details > summary::after { content: ""; width: 9px; height: 9px; border-right: 2px solid var(--ink-3);
  border-bottom: 2px solid var(--ink-3); transform: rotate(45deg); transition: transform .15s; flex: none; }
.curric > details[open] > summary::after { transform: rotate(-135deg); }
.curric .lessons { padding: 4px 22px 16px 70px; }
.curric .lesson { display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 11px 0;
  border-top: 1px solid var(--line); font-size: 14.5px; color: var(--ink-2); position: relative; }
.curric .lesson::before { content: ""; position: absolute; left: -20px; top: 50%; width: 6px; height: 6px;
  border-radius: 50%; background: var(--line-2); transform: translateY(-50%); }
.curric .lesson .free { display: inline-flex; align-items: center; gap: 5px; font-size: 12.5px; font-weight: 700;
  padding: 5px 13px; border-radius: var(--radius-pill); background: var(--lime); color: var(--ink); }
.curric .lesson .free svg { width: 14px; height: 14px; }
/* a free-preview lesson row is a link into the player */
.curric a.lesson-preview { text-decoration: none; color: var(--ink); cursor: pointer; }
.curric a.lesson-preview:hover { color: var(--ink); }
.curric a.lesson-preview:hover .free { box-shadow: 0 0 0 3px var(--lime-wash); }

/* sticky enroll box (course-detail) */
/* sticky now lives on the grid item (.with-rail > aside), not here — see layout primitives */
.enroll { border: 1px solid var(--line); border-radius: var(--radius-lg); padding: 30px; background: var(--surface); }
.enroll .price { display: block; font-family: var(--font-serif); font-size: 2.2rem; font-weight: 600; color: var(--ink); margin-bottom: 4px; }
.enroll .price small { font-family: var(--font-sans); font-size: .9rem; font-weight: 500; color: var(--ink-3); }
.enroll .esub { color: var(--ink-3); font-size: 13.5px; margin-bottom: 20px; }
.enroll .btn { width: 100%; justify-content: center; margin-bottom: 10px; }
.enroll ul { margin-top: 20px; padding-top: 20px; border-top: 1px solid var(--line); }

/* video box (marketing) + course player video (dark, in-lesson) */
.videobox { border: 1px solid var(--line); border-radius: var(--radius-lg); aspect-ratio: 16/10; background: var(--paper-2);
  display: grid; place-items: center; overflow: hidden; }
.videobox .play { width: 64px; height: 64px; border-radius: 50%; background: var(--surface);
  border: 1px solid var(--line); display: grid; place-items: center; color: var(--ink); cursor: pointer; }
.videobox .play svg { width: 24px; height: 24px; margin-left: 3px; }
.pl-video { aspect-ratio: 16/9; border-radius: var(--radius-lg); background: linear-gradient(135deg, #1b1e27, #33384a);
  display: grid; place-items: center; margin-bottom: 20px; }
.pl-play { background: rgba(255,255,255,.14); border: none; color: #fff; width: 68px; height: 68px; border-radius: 50%;
  display: grid; place-items: center; cursor: pointer; }
.pl-play svg { width: 30px; height: 30px; margin-left: 3px; }

/* course player: sticky curriculum sidebar + lesson content */
.pl { display: grid; grid-template-columns: 300px minmax(0, 1fr); gap: 40px; align-items: start; }
.pl-side { border: 1px solid var(--line); border-radius: var(--radius); padding: 20px 18px; position: sticky;
  top: calc(var(--nav-h) + 20px); background: var(--surface); }
.pl-back { display: inline-flex; align-items: center; gap: 6px; font-size: 13.5px; font-weight: 600; color: var(--ink-3);
  margin-bottom: 16px; text-decoration: none; }
.pl-back:hover { color: var(--ink); text-decoration: none; }
.pl-back svg { width: 15px; height: 15px; }
.pl-side h3 { font-size: 1rem; margin-bottom: 10px; }
.pl-chapter { margin-top: 18px; }
.pl-ch { font-size: 11.5px; font-weight: 700; letter-spacing: .04em; color: var(--ink-3); text-transform: uppercase; margin-bottom: 8px; }
.pl-lesson { display: flex; align-items: center; gap: 10px; padding: 9px 10px; border-radius: var(--radius-sm);
  font-size: 13.5px; color: var(--ink-2); text-decoration: none; }
.pl-lesson:hover { background: var(--paper-2); color: var(--ink); text-decoration: none; }
/* current relies on the row highlight alone — its icon gets no chip of its own, nothing competes
   with the row itself for attention. Done = the one state that earns solid lime (an achievement
   marker, not decoration). Locked = same neutral wash-chip shape every decorative icon uses,
   muted color so it still reads as unavailable, not as something to notice. */
.pl-lesson.current { background: var(--lime-wash); color: var(--ink); font-weight: 600; }
.pl-lesson.locked { color: var(--ink-3); pointer-events: none; }
.pl-ic { width: 28px; height: 28px; border-radius: 50%; flex: none; display: grid; place-items: center; }
.pl-ic svg { width: 15px; height: 15px; }
.pl-lesson.done .pl-ic { background: var(--lime); color: var(--ink); }
.pl-lesson.locked .pl-ic { background: var(--lime-wash); color: var(--ink-3); }
.pl-t { flex: 1; min-width: 0; }
.pl-d { font-size: 11.5px; color: var(--ink-3); flex: none; }
.pl-nav { display: flex; justify-content: space-between; gap: 14px; margin: 24px 0; flex-wrap: wrap; }
.pl-panel h3 { font-size: 1.1rem; margin: 22px 0 10px; }
.pl-panel .btn-row { margin-top: 4px; }
/* resource downloads are just btn-line btn-sm with a download icon — not a 6th bespoke button
   style. Reuse the system instead of inventing a look-alike. */

/* ---------------- auth pages (signin/signup/forgot/reset/verify) ---------------- */
.authwrap { min-height: 100vh; display: grid; place-items: center; padding: 48px 20px; }
.authcard { width: 100%; max-width: 460px; }
.authcard .top { text-align: center; margin-bottom: 26px; }
.authbox { border: 1px solid var(--line); border-radius: var(--radius-lg); padding: 38px 36px; background: var(--surface); }
.authbox.center { text-align: center; }
.authbox h1 { font-size: 1.6rem; margin-bottom: 8px; }
.authbox .sub { color: var(--ink-3); font-size: 15px; margin-bottom: 26px; line-height: 1.5; }
.authicon { width: 56px; height: 56px; border-radius: var(--radius); display: grid; place-items: center;
  margin: 0 auto 20px; background: var(--lime-wash); color: var(--lime-text); }
.authicon svg { width: 26px; height: 26px; }
.oauth { display: grid; gap: 12px; margin-bottom: 4px; }
.oauth .btn { width: 100%; justify-content: center; }
.divider { display: flex; align-items: center; gap: 14px; color: var(--ink-3); font-size: 13px; margin: 22px 0; }
.divider::before, .divider::after { content: ""; flex: 1; height: 1px; background: var(--line); }
.authalt { text-align: center; margin-top: 20px; font-size: 14.5px; color: var(--ink-3); }
.authfoot { text-align: center; margin-top: 20px; font-size: 12.5px; color: var(--ink-3); }
.authfoot a { color: var(--ink-3); text-decoration: underline; }
/* a real <button> that reads as an inline text link (e.g. "Resend code" that must POST) */
/* a real <button> that reads as an inline text link (e.g. "Resend code" that must POST) — small
   extension; no documented equivalent (all other buttons are .btn-*) */
.linkbtn { background: none; border: 0; padding: 0; font: inherit; color: var(--lime-text); font-weight: 600; cursor: pointer; text-decoration: underline; }
.linkbtn:hover { opacity: .8; }

/* ---------------- feedback: top progress bar, button working-state, note fade-in ---------------- */
/* thin bar that fills across the top during page navigation (like the one on Google/YouTube) */
#ns-progress {
  position: fixed; top: 0; left: 0; height: 2.5px; width: 0;
  background: var(--lime-hover); z-index: 10000; opacity: 0; border-radius: 0 2px 2px 0;
  transition: width .2s ease, opacity .3s ease; pointer-events: none;
}
#ns-progress.active { opacity: 1; }
@media (prefers-reduced-motion: reduce) { #ns-progress { transition: opacity .2s ease; } }

/* a button that has triggered an action: dimmed, non-interactive, shows it is working */
.btn.is-loading { opacity: .6; pointer-events: none; cursor: progress; }

/* status notes and inline errors ease in instead of snapping */
.form-note, .field-err { animation: ns-fade-in .22s ease; }
@keyframes ns-fade-in { from { opacity: 0; transform: translateY(-3px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .form-note, .field-err { animation: none; } }

/* ================= Events (admin) ================= */
/* admin filter tabs (Upcoming / Drafts / Finished) — admin-only, no public equivalent */
.admin-tabs { display: flex; gap: 4px; border-bottom: 1px solid var(--line); margin-bottom: 22px; }
.admin-tabs a { padding: 10px 16px; font-size: 14.5px; font-weight: 600; color: var(--ink-3); border-bottom: 2px solid transparent; margin-bottom: -1px; }
.admin-tabs a.on { color: var(--ink); border-bottom-color: var(--ink); }
.admin-tabs a:hover { color: var(--ink); }
/* column templates that extend the documented .ptable (see "tables") */
.ptable-regs .ptable-row { grid-template-columns: 2fr 1.3fr 1.3fr; }
/* curriculum builder: chapter cards, each with nested lesson rows */
.course-curric > .repeat-rows { display: grid; gap: 14px; }
.repeat-row.course-chapter { display: block; padding: 14px; border: 1px solid var(--line-2); border-radius: 12px; background: var(--paper); }
.course-chapter-head { display: flex; gap: 10px; align-items: center; margin-bottom: 12px; }
.course-chapter-head .ch-title { flex: 1; font-weight: 600; }
.course-lessons > .repeat-rows { display: grid; gap: 8px; }
.repeat-row.course-lesson { display: flex; gap: 8px; align-items: center; }
.course-lesson .ls-dur { flex: 0 0 90px; }
.course-lesson .ls-free { flex: 0 0 150px; }
.course-lessons .repeat-add { margin-top: 10px; }
/* column templates for the two-pane detail tables (enrolled / owners / billing / participants) */
.ptable-wf3 .ptable-row { grid-template-columns: 2.4fr 1fr 1.1fr; }
.ptable-wf4 .ptable-row { grid-template-columns: 1.8fr 1.1fr 1fr 1fr; }
.ptable-wf5 .ptable-row { grid-template-columns: 2fr 1fr 1.1fr 1fr .9fr; }
.ptable-wf6 .ptable-row { grid-template-columns: 1.6fr 1.6fr 1.5fr .8fr .8fr auto; }
.cert-acts { display: inline-flex; gap: 6px; flex-wrap: wrap; }
.cert-link { display: inline-flex; align-items: center; gap: 5px; color: var(--lime-text); font-weight: 600; }
.cert-link svg { width: 14px; height: 14px; }
.ptable-wfev .ptable-row { grid-template-columns: 1.6fr 2fr 1fr; }
.ptable-act { display: flex; justify-content: flex-end; }
/* admin key/value detail list (user view, etc.) */
.uv-detail { display: grid; grid-template-columns: 130px 1fr; gap: 10px 18px; margin-bottom: 18px; font-size: 14.5px; }
.uv-detail dt { color: var(--ink-3); }
.uv-detail dd { color: var(--ink); }
/* user "My resources" card (owned resource + its download buttons) */
.myres-card { border: 1px solid var(--line); border-radius: var(--radius-lg); padding: 22px; background: var(--surface); }
.myres-head { display: flex; gap: 14px; align-items: flex-start; margin-bottom: 16px; }
.myres-title { display: block; font-size: 1.1rem; font-weight: 700; color: var(--ink); }
.myres-title:hover { color: var(--lime-text); }
.myres-meta { display: block; font-size: 13px; color: var(--ink-3); margin-top: 3px; }
.myres-files { display: flex; flex-wrap: wrap; gap: 10px; }
.myres-upsell { display: inline-flex; align-items: center; gap: 6px; margin-top: 14px; font-size: 13.5px; font-weight: 600; color: var(--lime-text); }
.myres-upsell svg { width: 15px; height: 15px; }
/* icon+title+body and file repeat rows extend .repeat-row (see forms) */
.repeat-trio { flex-wrap: wrap; padding: 12px; border: 1px solid var(--line); border-radius: 10px; position: relative; }
.repeat-trio .r-icon { flex: 0 0 120px; }
.repeat-trio .r-title { flex: 1 1 180px; }
.repeat-trio .r-body { flex: 1 1 100%; }
.repeat-trio .repeat-del, .repeat-file .repeat-del { position: absolute; top: 8px; right: 8px; width: 30px; height: 30px; font-size: 16px; }
.repeat-file { flex-wrap: wrap; align-items: center; padding: 12px; border: 1px solid var(--line); border-radius: 10px; position: relative; }
.repeat-file .r-file { flex: 1 1 240px; }
.repeat-file .r-label { flex: 1 1 160px; }
.repeat-file .r-tier { flex: 0 0 130px; }
.repeat-row .r-mini { flex: 0 0 130px; }   /* narrow icon-name input in an icon+label row */
.res-filelist { display: grid; gap: 8px; margin-bottom: 14px; }
.res-fileitem { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; padding: 10px 14px; border: 1px solid var(--line); border-radius: 10px; font-size: 14px; }
.res-fileitem .rf-name { font-weight: 600; }
.res-fileitem .rf-rm { margin-left: auto; display: flex; align-items: center; gap: 6px; font-size: 12.5px; color: var(--ink-3); }
.back-link { display: inline-flex; align-items: center; gap: 6px; font-size: 13.5px; font-weight: 600; color: var(--ink-3); margin-bottom: 8px; }
.back-link:hover { color: var(--ink); }
.back-link svg { width: 15px; height: 15px; }
.ev-statusbar { display: flex; flex-wrap: wrap; gap: 16px; justify-content: space-between; align-items: center; padding: 16px 18px; border: 1px solid var(--line); border-radius: 12px; margin-bottom: 16px; }
.ev-reglink { display: inline-block; margin-top: 6px; font-size: 13.5px; font-weight: 600; color: var(--lime-text); }
.ev-share { padding: 16px 18px; border: 1px solid var(--line); border-radius: 12px; margin-bottom: 24px; }
.ev-share label { display: block; font-size: 13px; font-weight: 600; color: var(--ink-3); margin-bottom: 8px; }
.ev-share-row { display: flex; gap: 10px; }
.ev-share-row input { flex: 1; }
.ev-img-current { margin-bottom: 12px; }
.ev-img-current img { max-width: 320px; width: 100%; border-radius: 10px; border: 1px solid var(--line); }
/* form section headings (Basics, Password, ...) must be small labels, not page-size headings */
.set-block h2 { font-size: 1.15rem; line-height: 1.3; margin-bottom: 16px; }
.ev-form { max-width: 780px; }
.adm-detail .ev-form { max-width: none; }   /* in the two-pane detail the form fills the pane (full width) */
.ev-form .set-block { margin-bottom: 40px; padding-bottom: 40px; border-bottom: 1px solid var(--line); }
.ev-form .set-block:last-of-type { border-bottom: none; padding-bottom: 0; }
.ev-form .set-block > .hint { margin-top: -6px; margin-bottom: 14px; }
.ev-form input[type="file"] { padding: 10px 12px; background: var(--paper); cursor: pointer; }

/* universal sticky action bar: Save/Cancel etc. stay pinned to the bottom while the form scrolls */
.form-actionbar { position: sticky; bottom: 16px; display: flex; flex-wrap: wrap; gap: 12px; align-items: center;
  padding: 14px 18px; margin-top: var(--sp-4); background: #fff; border: 1px solid var(--line-2); border-radius: 14px;
  box-shadow: 0 8px 30px rgba(0,0,0,.08); z-index: 30; }
@media (prefers-reduced-motion: no-preference) { .form-actionbar { transition: box-shadow .2s; } }
/* repeatable rows (bullets, FAQs) */
.repeat-rows { display: grid; gap: 10px; margin-bottom: 12px; }
.repeat-row { display: flex; gap: 10px; align-items: flex-start; }
/* controls that aren't inside a .field reuse the documented .field control styling (border/padding +
   the select chevron rule below); nothing new, just extended to these contexts */
.repeat-row input, .repeat-row textarea, .repeat-row select, .res-fileitem select, .ev-share-row input,
.master-row input, .master-row select, .master-add input, .master-add select {
  flex: 1; width: 100%; border: 1.5px solid var(--line-2); border-radius: var(--radius-sm);
  padding: 13px 16px; font-size: 16px; font-family: inherit; color: var(--ink);
  background-color: var(--surface); transition: border-color .15s; }
.repeat-row input:focus, .repeat-row textarea:focus, .repeat-row select:focus, .res-fileitem select:focus, .ev-share-row input:focus,
.master-row input:focus, .master-row select:focus, .master-add input:focus, .master-add select:focus { outline: none; border-color: var(--ink); }
.repeat-row textarea { resize: vertical; min-height: 70px; }
.res-fileitem select { flex: 0 0 140px; width: auto; }   /* file-tier select stays compact in its row */
.repeat-row select, .res-fileitem select, .master-row select, .master-add select { padding-right: 42px; }   /* room for the chevron (the shorthand above resets it) */
.repeat-faq { flex-direction: column; padding: 14px; border: 1px solid var(--line); border-radius: 10px; }
.repeat-faq { position: relative; }
.repeat-del { flex: none; width: 38px; height: 42px; border: 1px solid var(--line); border-radius: 8px; background: #fff; color: var(--ink-3); font-size: 20px; line-height: 1; cursor: pointer; }
.repeat-del:hover { color: var(--err); border-color: var(--err); }
.repeat-faq .repeat-del { position: absolute; top: 10px; right: 10px; width: 30px; height: 30px; font-size: 16px; }
/* image grid in the editor */
.ev-imggrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: 12px; margin-bottom: 14px; }
.ev-imgitem { display: block; border: 1px solid var(--line); border-radius: 10px; overflow: hidden; cursor: pointer; }
.ev-imgitem img { width: 100%; height: 110px; object-fit: cover; display: block; }
.ev-imgrm { display: flex; align-items: center; gap: 6px; padding: 8px 10px; font-size: 12.5px; color: var(--ink-3); }
/* prominent registered count (admin list + edit) */
.ev-reglink { display: inline-flex; align-items: baseline; gap: 6px; margin-top: 8px; font-weight: 600; color: var(--lime-text); }
.ev-reglink b { font-size: 20px; color: var(--ink); }
/* participant + message lists REUSE the documented .ptable / .ptable-row / .ptable-head (see "tables").
   Only the additions unique to them live here: a big count stat, extra column templates, a sortable
   header link, a clickable-row modifier, pagination, and the nav unread badge. */
.reg-stat { display: flex; align-items: baseline; gap: 10px; margin-bottom: 24px; }   /* big count above a .ptable */
.reg-stat-num { font-size: 2.6rem; font-weight: 800; line-height: 1; letter-spacing: -.02em; }
.reg-stat-label { color: var(--ink-3); font-size: 15px; }
.ptable-msg .ptable-row { grid-template-columns: 1.4fr 2fr 1.4fr .8fr; }               /* messages: 4 columns */
.ptable-sort { color: inherit; }                                                       /* sortable column header link inside .ptable-head */
.ptable-sort:hover { color: var(--ink); }
.ptable-row.msgrow { cursor: pointer; }                                                /* a .ptable-row that opens a modal */
.ptable-row.msgrow:hover { background: var(--paper-2); }
.msgrow.is-handled { opacity: .55; }
.msgrow span[data-l="Subject"] { color: var(--ink); font-weight: 600; }
.msg-status { font-size: 12px; font-weight: 700; color: var(--ink-3); }
.msg-status.is-new { color: var(--lime-text); display: inline-flex; align-items: center; gap: 6px; }
.msg-status.is-new::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: var(--lime-text); }
.msg-from { font-size: 13.5px; color: var(--ink-3); }
.msg-from a { color: var(--lime-text); font-weight: 600; }
.msg-body { color: var(--ink-2); line-height: 1.7; white-space: pre-line; }
/* pagination — ONE component sitewide (unified 2026-08-28; replaced the separate .pager + .pagination).
   Works for server-rendered <a> links (admin lists) AND JS-generated <button>s (public catalog). */
.pager { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; justify-content: center; margin-top: var(--sp-5); }
.pager a, .pager button { min-width: 40px; height: 40px; padding: 0 12px; display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--line-2); border-radius: var(--radius-sm); background: var(--surface); font: inherit; font-size: 14px; font-weight: 600;
  color: var(--ink-2); cursor: pointer; text-decoration: none; }
.pager a:hover:not(.on), .pager button:hover:not(:disabled):not(.on) { border-color: var(--ink); color: var(--ink); text-decoration: none; }
.pager .on { background: var(--ink); color: #fff; border-color: var(--ink); cursor: default; }
.pager button:disabled { opacity: .4; cursor: not-allowed; }
.pager .gap { border: none; background: none; cursor: default; min-width: 20px; color: var(--ink-3); }
/* compact variant for the admin two-pane rail footer */
.pager.pager-sm { margin: 0; gap: 5px; }
.pager.pager-sm a, .pager.pager-sm button { min-width: 32px; height: 32px; padding: 0 9px; font-size: 13px; border-radius: 7px; }
/* admin left-nav unread count badge */
.asi-badge { margin-left: auto; min-width: 20px; height: 20px; padding: 0 6px; border-radius: 10px; background: var(--lime); color: var(--lime-text); font-size: 12px; font-weight: 800; display: inline-flex; align-items: center; justify-content: center; }
/* the message modal reuses the documented .modal component (see "modal" section below) */
.modal-box.msg-modal-box { max-width: 680px; }
.modal-box.scroll.msg-modal-box .modal-body { border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); padding-block: 18px; margin-bottom: var(--sp-2); }
.modal-box.msg-modal-box .modal-actions { justify-content: flex-start; }

/* ================= Event public page (uses the documented header-public brand-only + footer-public;
   these are just the page's own content components) ================= */


/* details: individual small cards, one per fact */
.evp-detailcard { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 14px; }
.evp-fact { display: flex; gap: 12px; align-items: flex-start; padding: 16px 18px; background: #fff; border: 1px solid var(--line); border-radius: 14px; }
.evp-fact svg { width: 22px; height: 22px; flex: none; color: var(--lime-text); margin-top: 1px; }
.evp-fact-l { display: block; font-size: 12.5px; color: var(--ink-3); margin-bottom: 2px; }
.evp-fact-v { display: block; font-size: 15.5px; font-weight: 600; }

.evp-note { display: flex; gap: 12px; align-items: flex-start; padding: 16px 18px; background: #fff; border: 1px solid var(--line); border-radius: 12px; }
.evp-note svg { width: 22px; height: 22px; flex: none; color: var(--lime-text); }
.evp-note p { color: var(--ink-2); }

.evp-list { list-style: none; display: grid; gap: 12px; }
.evp-list li { display: flex; gap: 12px; align-items: flex-start; }
.evp-list li svg { width: 16px; height: 16px; flex: none; color: var(--lime-text); margin-top: 4px;
  background: var(--lime); border-radius: 6px; padding: 5px; box-sizing: content-box; }
.evp-list li span { color: var(--ink-2); line-height: 1.55; padding-top: 3px; }

.evp-gallery { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 14px; }
.evp-shot { aspect-ratio: 4/3; border-radius: 12px; border: 1px solid var(--line); }
.evp-shot img { width: 100%; height: 100%; object-fit: cover; max-width: none; }

/* sticky registration card (right rail) */
.evp-card { background: #fff; border: 1px solid var(--line); border-radius: 18px; padding: var(--sp-4); }
.evp-card h2 { font-size: 1.35rem; margin-bottom: 8px; }
.evp-card-when { display: flex; gap: 12px; align-items: center; padding-bottom: 16px; margin-bottom: 18px; border-bottom: 1px solid var(--line); }
.evp-card-when svg { width: 26px; height: 26px; color: var(--lime-text); flex: none; }
.evp-card-when strong { display: block; font-size: 15px; }
.evp-card-when span { display: block; font-size: 13.5px; color: var(--ink-3); }
.evp-form { margin-top: 16px; }
.evp-seats { margin-top: 12px; text-align: center; font-size: 13px; font-weight: 600; color: var(--lime-text); }
.evp-hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

/* card states: registered / already / ended */
.evp-state { text-align: center; padding: 6px 0; }
.evp-state > svg { width: 32px; height: 32px; color: var(--lime-text); background: var(--lime-wash); border-radius: 50%; padding: 13px; box-sizing: content-box; margin: 0 auto 16px; display: block; }
.evp-state h2 { margin-bottom: 8px; }
.evp-state p { color: var(--ink-2); margin-bottom: 8px; }
.evp-spam { font-size: 13px; color: var(--ink-3); background: var(--paper); border-radius: 8px; padding: 10px 12px; }
/* an ended/full/closed event: the whole card turns amber so it clearly reads as "not open" */
.evp-card-over { background: #fffaf0; border-color: #f0d9a8; }
.evp-over > svg { color: #9a6b00; background: #fdf3e0; }
.evp-over h2 { font-size: 1.4rem; }

/* ---------------- account portal shared ---------------- */
.pagehead { padding: var(--section-y) 0 0; border-bottom: 1px solid var(--line); }
.pagehead h1 { margin-bottom: 6px; }
.pagehead .sub { margin-bottom: 22px; }
.section-sm { padding: var(--section-y) 0; }
.narrow { max-width: 900px; }
.block-title { font-size: 1.25rem; margin: 36px 0 16px; }
.block-title:first-child { margin-top: 4px; }
.block-title + .lead { margin-bottom: var(--sp-4); }

.learn-list { display: grid; gap: 14px; }
.learn-card { display: flex; align-items: center; gap: 18px; border: 1px solid var(--line); border-radius: var(--radius);
  padding: 18px 20px; background: var(--surface); }
.learn-thumb { width: 58px; height: 58px; flex: none; border-radius: var(--radius-sm); display: grid; place-items: center;
  background: var(--lime-wash); color: var(--lime-text); }
.learn-thumb svg { width: 28px; height: 28px; }
.learn-body { flex: 1; min-width: 0; }
.learn-body b { display: block; margin-bottom: 4px; }
.learn-body .prog { margin-top: 10px; }
.learn-card .btn { flex: none; }

/* NorthStar licence card (distinctive — ties account to the desktop app) */
.lic-card { border: 1px solid var(--line); border-radius: var(--radius-lg); padding: 28px; background: var(--surface); }
.lic-head { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; }
.lic-mark { width: 52px; height: 52px; flex: none; border-radius: var(--radius); display: grid; place-items: center;
  background: var(--lime-wash); color: var(--lime-text); }
.lic-mark svg { width: 26px; height: 26px; }
.lic-head b { display: block; font-size: 1.05rem; }
.lic-head .tag { margin-left: auto; }
.lic-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 18px 24px; margin: 24px 0;
  padding: 22px 0; border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }
.lic-grid span { display: block; font-size: 12.5px; color: var(--ink-3); margin-bottom: 3px; }
.lic-grid b { font-size: 14.5px; }
.lic-grid .key { font-variant-numeric: tabular-nums; letter-spacing: .01em; }
.lic-actions { display: flex; gap: 12px; flex-wrap: wrap; }
.lic-note { font-size: 13.5px; color: var(--ink-3); margin-top: 18px; line-height: 1.6; }

/* ---------------- checkout ---------------- */
.co { display: grid; grid-template-columns: minmax(0,1fr) 360px; gap: 56px; align-items: start; }
.co-block { padding: 26px 0 4px; border-top: 1px solid var(--line); margin-top: 26px; }
.co-block:first-of-type { border-top: none; margin-top: 22px; padding-top: 4px; }
.co-block h2 { font-size: 1.3rem; margin-bottom: 16px; }
.grid2 { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.form-hint { font-size: 13.5px; color: var(--ink-3); margin-top: 6px; }
.paytabs { display: flex; gap: 10px; margin-bottom: 16px; flex-wrap: wrap; }
.paytab { display: inline-flex; align-items: center; gap: 8px; border: 1px solid var(--line-2); border-radius: var(--radius-sm);
  padding: 10px 15px; font-size: 14.5px; font-weight: 600; color: var(--ink-2); cursor: pointer; }
.paytab input { accent-color: var(--lime); }
.pay-note { display: flex; align-items: center; gap: 8px; font-size: 13px; color: var(--ink-3); margin-top: 12px; }
.pay-note svg { width: 16px; height: 16px; flex: none; color: var(--lime-text); }
.co-summary { border: 1px solid var(--line); border-radius: var(--radius-lg); padding: 24px 22px; background: var(--surface);
  position: sticky; top: calc(var(--nav-h) + 24px); }
.co-summary h3 { font-size: 1.1rem; margin-bottom: 16px; }
.co-item { display: flex; gap: 14px; align-items: flex-start; padding-bottom: 18px; border-bottom: 1px solid var(--line); }
.co-thumb { width: 48px; height: 48px; border-radius: var(--radius-sm); flex: none; display: grid; place-items: center;
  background: var(--lime-wash); color: var(--lime-text); }
.co-thumb svg { width: 22px; height: 22px; }
.co-item b { display: block; font-size: 14.5px; }
.co-item span { font-size: 12.5px; color: var(--ink-3); }
.co-line { display: flex; justify-content: space-between; font-size: 14.5px; color: var(--ink-2); padding: 12px 0 0; }
.co-line.total { font-size: 1.2rem; font-weight: 700; color: var(--ink); border-top: 1px solid var(--line);
  margin-top: 8px; padding-top: 14px; }
.co-coupon { display: flex; gap: 8px; margin: 12px 0 4px; }
.co-coupon input { flex: 1; }
.co-perks { list-style: none; margin: 18px 0 0; padding: 16px 0 0; border-top: 1px solid var(--line); display: grid; gap: 9px; }
.co-perks li { display: flex; align-items: flex-start; gap: 9px; font-size: 13.5px; color: var(--ink-2); }
.co-perks svg { width: 15px; height: 15px; flex: none; margin-top: 2px; color: var(--ok-vivid); }

/* ---------------- invoice document ---------------- */
.invoice { border: 1px solid var(--line); border-radius: var(--radius-lg); padding: 36px; margin-top: 14px;
  background: var(--surface); }
.inv-top { display: flex; justify-content: space-between; align-items: flex-start; gap: 20px; padding-bottom: 24px;
  border-bottom: 1px solid var(--line); }
.inv-top .brand { font-size: 24px; }
.inv-meta { text-align: right; display: grid; gap: 4px; justify-items: end; }
.inv-meta b { font-size: 1rem; }
.inv-parties { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; padding: 22px 0; }
.inv-parties h4 { font-size: 12px; text-transform: uppercase; letter-spacing: .02em; color: var(--ink-3); margin-bottom: 6px; }
.inv-parties p { color: var(--ink-2); line-height: 1.6; }
.inv-totals { max-width: 300px; margin-left: auto; padding-top: 6px; }
.invoice + .btn-row { margin-top: var(--sp-4); }

/* ---------------- admin dashboard content ---------------- */
.admin-top { display: flex; justify-content: space-between; align-items: center; gap: 20px; margin-bottom: 28px; }
.admin-top h1 { font-size: 1.6rem; }
.admin-chip { display: inline-flex; align-items: center; gap: 10px; font-weight: 600; font-size: 14.5px; }
.admin-chip .avatar { width: 32px; height: 32px; font-size: 12px; }
.admin-stats { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.admin-grid { display: grid; grid-template-columns: minmax(0,1.4fr) minmax(0,1fr); gap: 20px; margin-top: 22px; align-items: start; }
.admin-card { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); padding: var(--sp-25); }
.admin-card-h { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: var(--sp-2); }
.admin-card-h h2 { font-size: 1.1rem; }

/* ---- Icons reference (admin-only): read-only, searchable grid of every ns_icon(). 100px tiles,
   click-to-copy the name. Not a two-pane page. ---- */
.icons-top { position: sticky; top: 0; z-index: 4; background: var(--paper); display: flex; align-items: center; gap: var(--sp-3); padding-bottom: var(--sp-2); border-bottom: 1px solid var(--line); }
.icons-search { flex: 1; max-width: 420px; }
.icons-count { color: var(--ink-3); font-size: var(--text-sm); font-weight: 600; white-space: nowrap; }
.icons-hint { margin: var(--sp-2) 0 var(--sp-3); }
.icons-hint code { background: var(--paper-2); border-radius: 6px; padding: 1px 6px; font-family: var(--font-sans); font-weight: 600; color: var(--ink-2); }
.icongrid { display: grid; grid-template-columns: repeat(auto-fill, 100px); gap: var(--sp-15); }
.iconcell { position: relative; width: 100px; height: 100px; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--sp-1); padding: var(--sp-1); border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); cursor: pointer; color: var(--ink); transition: border-color .12s, background .12s, transform .12s; }
.iconcell:hover { border-color: var(--line-2); background: var(--paper-2); transform: translateY(-2px); }
.iconcell:focus-visible { outline: none; border-color: var(--ink); box-shadow: 0 0 0 3px var(--lime-wash); }
.iconcell-ic svg { width: 28px; height: 28px; display: block; }
.iconcell-name { max-width: 84px; font-size: var(--text-xs); color: var(--ink-3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.iconcell-copied { position: absolute; inset: 0; display: grid; place-items: center; background: var(--lime-wash); color: var(--lime-text); font-size: var(--text-sm); font-weight: 700; border-radius: var(--radius); opacity: 0; pointer-events: none; transition: opacity .12s; }
.iconcell.copied .iconcell-copied { opacity: 1; }
/* a class rule (.iconcell{display:flex}) outranks the UA [hidden] rule, so hiding must be re-asserted here */
.iconcell[hidden], .icongrid-empty[hidden] { display: none; }
.icons-top .btn { flex: none; align-self: stretch; }
.icongrid-empty { margin-top: var(--sp-5); }
.icongrid-pager { margin-top: var(--sp-4); justify-content: center; }
.link { font-size: 13.5px; font-weight: 600; color: var(--lime-text); }
.mini-list { display: grid; gap: 2px; }
.mini-row { display: flex; align-items: center; gap: 12px; padding: 10px 0; border-top: 1px solid var(--line); }
.mini-row:first-child { border-top: none; }
a.mini-row:hover { background: var(--paper-2); text-decoration: none; }
.mini-row > div { flex: 1; min-width: 0; }
.mini-row b { display: block; font-size: 14px; }
.admin-toolbar { display: flex; gap: 12px; justify-content: space-between; align-items: center; margin-bottom: 18px; flex-wrap: wrap; }
.admin-toolbar input { flex: 1; min-width: 220px; }

/* ---------------- admin two-pane (master-detail) shell (2026-08-28) ----------------
   Shared skeleton for the management pages (users, courses, resources, events, masters, orders,
   enrollments, messages): a fixed-height left rail (search + list + pagination, only the list scrolls)
   beside a detail pane (fixed header + tabs, only the body scrolls). The PAGE never scrolls. Reuses
   .avatar .admin-card .admin-card-h .drow .tag .btn .admin-tabs .stat-row .statcard .pager .ptable.
   Add-only new pieces: this shell, .rowlink (clickable data row), .ptable-foot (totals row). */
.admin-main.admin-split { height: 100vh; overflow: hidden; display: flex; flex-direction: column; padding: 20px 26px; }
.admin-main.admin-split > .form-note.flash { flex: none; margin: 0 0 12px; }
.adm-split { flex: 1; min-height: 0; display: grid; grid-template-columns: 340px minmax(0,1fr); grid-template-rows: minmax(0,1fr); gap: 20px; }
/* left rail */
.adm-rail { min-height: 0; display: grid; grid-template-rows: auto minmax(0,1fr) auto; background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-lg); overflow: hidden; }
.adm-rail-top { padding: var(--sp-2); border-bottom: 1px solid var(--line); display: grid; gap: var(--sp-15); }
.adm-search { position: relative; }
.adm-search svg { position: absolute; left: 14px; top: 50%; transform: translateY(-50%); width: 18px; height: 18px; color: var(--ink-3); pointer-events: none; }
.adm-search input { width: 100%; border: 1.5px solid var(--line-2); border-radius: var(--radius-sm); padding: var(--sp-15) var(--sp-2) var(--sp-15) 42px; font: inherit; font-size: var(--text-base); color: var(--ink); background: var(--surface); }
.adm-search input:focus { outline: none; border-color: var(--ink); box-shadow: 0 0 0 3px var(--lime-wash); }
.adm-count { display: flex; justify-content: space-between; align-items: center; font-size: var(--text-sm); font-weight: 600; color: var(--ink-3); }
.adm-list { overflow-y: auto; min-height: 0; }
.adm-item { display: grid; gap: var(--sp-05); padding: var(--sp-15) var(--sp-2); border-bottom: 1px solid var(--line); cursor: pointer; color: inherit; transition: background .12s; }
.adm-item:last-child { border-bottom: none; }
.adm-item:hover { background: var(--paper-2); text-decoration: none; }
.adm-item.on { background: var(--lime-wash); box-shadow: inset 3px 0 0 var(--lime-hover); }
.adm-item .t { display: flex; justify-content: space-between; gap: var(--sp-15); align-items: center; font-weight: 600; font-size: var(--text-md); color: var(--ink); min-width: 0; }
.adm-item .t > span:first-child { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.adm-item .s { font-size: var(--text-sm); color: var(--ink-3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.adm-item.on .s { color: var(--lime-text); }
/* subtle list-item indicator (status / type / count). It sits on whichever row has less content:
   the title row (.t) for short-title lists, the sub row (.s-split) for long-title lists. Never a loud chip. */
.adm-item .s.s-split { display: flex; justify-content: space-between; gap: var(--sp-15); align-items: center; overflow: visible; }
.adm-item .s.s-split .s-main { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.adm-item .ind, .adm-item .s.s-split .s-right { flex: none; font-weight: 600; font-size: var(--text-xs); color: var(--ink-3); white-space: nowrap; }
.adm-item .ind.pub, .adm-item .s.s-split .s-right.pub { color: var(--lime-text); }
.adm-item .ind.err { color: var(--err); }
.adm-item.on .ind.pub { color: var(--lime-text); }
.adm-railfoot { padding: var(--sp-1) var(--sp-15); border-top: 1px solid var(--line); display: flex; justify-content: space-between; align-items: center; gap: var(--sp-15); }
.adm-railfoot .pg-info { font-size: var(--text-xs); color: var(--ink-3); font-weight: 600; }
/* right detail: fixed header (identity + actions + tabs) over a body that scrolls */
.adm-detail { min-height: 0; display: grid; grid-template-rows: auto minmax(0,1fr); background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-lg); overflow: hidden; }
.adm-dhead { padding: var(--sp-25) var(--sp-3) 0; border-bottom: 1px solid var(--line); }
.adm-dtop { display: flex; justify-content: space-between; align-items: flex-start; gap: var(--sp-3); padding-bottom: var(--sp-2); }
.adm-idb { display: flex; gap: var(--sp-2); align-items: center; min-width: 0; }
.adm-idb h2 { font-size: 1.35rem; line-height: 1.2; margin: 0 0 var(--sp-05); }
.adm-idb .sub { color: var(--ink-3); font-size: var(--text-sm); word-break: break-word; }
.adm-idb .chips { display: flex; gap: var(--sp-1); margin-top: var(--sp-1); flex-wrap: wrap; }
.adm-acts { display: flex; gap: var(--sp-1); flex-wrap: wrap; justify-content: flex-end; max-width: 58%; }
.adm-dhead .stat-row { margin: 2px 0 16px; }
.adm-dhead .admin-tabs { margin-bottom: 0; border-bottom: none; }
.adm-body { overflow-y: auto; min-height: 0; padding: var(--sp-25) var(--sp-3) var(--sp-3); background: var(--paper); }
.adm-tabpanel { display: none; }
.adm-tabpanel.on { display: block; }
/* While EDITING, the read-only tabs are hidden, so every editable panel (Course + Curriculum, marked
   .tab-edit) must show at once for a single scrolling Save. Read-only panels (e.g. Enrolled) stay hidden. */
.adm-detail.is-editing .adm-tabpanel.tab-edit { display: block; }
.adm-body .admin-card { margin-bottom: 16px; }
.adm-body .admin-card:last-child { margin-bottom: 0; }
.adm-body .admin-card .drow:first-child { padding-top: 0; }
.adm-body .admin-card .drow:last-child { padding-bottom: 0; }
/* detail placeholder when nothing is selected */
.adm-detail.is-empty { grid-template-rows: 1fr; place-items: center; }
/* clickable data row (generalizes the older .msgrow) + a totals row for .ptable */
.rowlink { cursor: pointer; }
.rowlink:hover { background: var(--paper-2); }
.ptable-foot .ptable-row { background: var(--paper-2); font-weight: 700; }
/* compact status filter in the rail count row */
.adm-count select { font: inherit; font-size: 12.5px; font-weight: 600; color: var(--ink-2); background: var(--surface); border: 1px solid var(--line-2); border-radius: 7px; padding: 4px 8px; cursor: pointer; }
/* editable public-link slug (admin edit mode): fixed prefix + editable slug segment */
.slug-edit { display: flex; align-items: stretch; border: 1.5px solid var(--line-2); border-radius: var(--radius-sm); overflow: hidden; background: var(--surface); }
.slug-edit .slug-prefix { display: flex; align-items: center; padding: 0 4px 0 14px; font-size: 13px; color: var(--ink-3); background: var(--paper-2); border-right: 1px solid var(--line-2); white-space: nowrap; overflow-x: auto; }
.slug-edit input { flex: 1; border: none !important; border-radius: 0 !important; box-shadow: none !important; min-width: 120px; }
.slug-row { display: flex; gap: 8px; align-items: center; }
.slug-row .slug-edit { flex: 1; }
/* multi-pick from a Masters list (What's inside, file formats): checkbox pills, selected = lime */
.pick-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.pick-chips label { display: inline-flex; align-items: center; gap: 7px; padding: 8px 13px; border: 1.5px solid var(--line-2); border-radius: var(--radius-pill); font-size: 13.5px; font-weight: 600; color: var(--ink-2); cursor: pointer; background: var(--surface); transition: border-color .12s, background .12s, color .12s; }
.pick-chips input { accent-color: var(--lime); margin: 0; }
.pick-chips label:hover { border-color: var(--ink-3); }
.pick-chips label:has(input:checked) { border-color: var(--lime); background: var(--lime-wash); color: var(--lime-text); }
.pick-chips label:has(input:disabled) { cursor: default; opacity: .8; }
.pick-chips label:has(input:disabled):hover { border-color: var(--line-2); }
.adm-detail:not(.is-editing) .pick-chips label:not(:has(input:checked)) { opacity: .45; }
/* universal image upload card: preview on the left, controls on the right. Reused for cover, instructor,
   user avatar, etc. In a locked (view) content detail it shows the picture with the controls disabled. */
.upload-card { display: flex; gap: 20px; align-items: center; padding: 16px; border: 1.5px dashed var(--line-2); border-radius: var(--radius-lg); background: var(--paper-2); }
.uc-preview { position: relative; width: 190px; height: 110px; flex: none; border-radius: var(--radius-sm); overflow: hidden; background: var(--surface); border: 1px solid var(--line); display: grid; place-items: center; }
.upload-card.uc-round .uc-preview { width: 110px; height: 110px; border-radius: 50%; }
.uc-preview .uc-img { width: 100%; height: 100%; object-fit: cover; display: block; }
.uc-preview .uc-ph { color: var(--ink-3); display: grid; place-items: center; }
.uc-preview .uc-ph svg { width: 34px; height: 34px; }
.uc-body { flex: 1; min-width: 0; }
.uc-title { font-weight: 600; font-size: 15px; color: var(--ink); }
.uc-hint { font-size: 13px; color: var(--ink-3); margin: 3px 0 12px; }
.uc-controls { display: flex; gap: 8px; align-items: stretch; max-width: 460px; }
.uc-controls .uc-browse { flex: none; }
.uc-controls .uc-path { flex: 1; min-width: 0; font: inherit; font-size: 14px; padding: 9px 13px; border: 1.5px solid var(--line-2); border-radius: var(--radius-sm); background: var(--surface); color: var(--ink-2); overflow: hidden; text-overflow: ellipsis; }
.uc-remove { margin-top: 12px; }
.uc-err { margin-top: 10px; }
/* locked (view) mode: solid border, picture shown, controls dimmed + disabled */
.adm-detail:not(.is-editing) .upload-card { border-style: solid; }
.adm-detail:not(.is-editing) .uc-controls { opacity: .5; }
@media (max-width: 620px) { .upload-card { flex-direction: column; align-items: flex-start; } .uc-preview { width: 100%; height: 150px; } }
/* single-form content detail (Courses/Resources/Events): the SAME form is the view. Not editing =
   fields locked (disabled + shown as clean values), section Add/Remove + Save/Cancel + file inputs hidden.
   Edit unlocks the same fields in place, so view and edit can never drift. */
.adm-detail.is-editing .cv-view { display: none; }          /* view-only chrome (tabs + row actions) */
.adm-detail .cv-edit-note { display: none; }
.adm-detail.is-editing .cv-edit-note { display: flex; align-items: center; gap: 8px; margin-top: 6px; flex-wrap: wrap; }
.adm-detail:not(.is-editing) .form-actionbar { display: none; }
/* The Curriculum tab mirrors the Course tab: a read-only outline by default (.curric-view), the interactive
   builder (.curric-edit) only in Edit mode. .curric-view carries .cv-view so it hides in edit mode too. */
.curric-edit, .test-edit { display: none; }
.adm-detail.is-editing .curric-edit, .adm-detail.is-editing .test-edit { display: block; }
.curric-view .cv-sub, .test-view .cv-sub { font-size: 12px; font-weight: 800; letter-spacing: .04em; text-transform: uppercase; color: var(--ink-3); margin: 0 0 12px; }
/* End-of-course test: read-only summary (view mode) */
.test-ro { margin: 0; padding-left: 20px; display: flex; flex-direction: column; gap: 16px; }
.test-ro-q { font-weight: 600; color: var(--ink); margin-bottom: 6px; }
.test-ro-opts { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 3px; }
.test-ro-opts li { color: var(--ink-3); font-size: 15px; }
.test-ro-opts li.ok { color: var(--ink); font-weight: 600; }
/* End-of-course test builder (edit mode) */
.tb-q { border: 1px solid var(--line); border-radius: 12px; margin-bottom: 14px; overflow: hidden; }
.tb-q-head { display: flex; align-items: center; gap: 10px; padding: 8px 12px; background: var(--paper-2); border-bottom: 1px solid var(--line); }
.tb-q-num { font-weight: 800; font-size: 12.5px; color: var(--ink-2); }
.tb-type { margin-right: auto; }
.tb-prompt { width: 100%; border: 0; border-bottom: 1px solid var(--line); border-radius: 0; padding: 12px; resize: vertical; }
.tb-opts { padding: 12px; display: flex; flex-direction: column; gap: 8px; align-items: flex-start; }
.tb-opt { display: flex; align-items: center; gap: 10px; width: 100%; }
.tb-opt input[type=radio], .tb-opt input[type=checkbox] { flex: none; width: 18px; height: 18px; }
.tb-opt-txt { flex: 1; }
.tb-addopt { margin-top: 2px; }
.curric-view .curric-ov { margin-bottom: 24px; }
.curric-view .rte-out { color: var(--ink-2); line-height: 1.6; }
.curric-view .rte-out > :first-child { margin-top: 0; }
.cro-meta { display: inline-flex; align-items: center; gap: 8px; color: var(--ink-3); }
.cro-meta svg { width: 15px; height: 15px; }
.cro-fc { display: inline-flex; align-items: center; gap: 3px; font-size: 12px; font-weight: 600; }
.cro-dur { font-size: 12.5px; }
/* read-only curriculum (admin Curriculum tab only): each lesson expands to show its rendered content */
.curric-view .curric .lessons { padding: 4px 22px 16px 50px; }
.cro-les { border-top: 1px solid var(--line); }
.cro-les > summary { list-style: none; cursor: pointer; display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 12px 20px; }
.cro-les > summary::-webkit-details-marker { display: none; }
.cro-les > summary::after { content: ""; width: 8px; height: 8px; border-right: 2px solid var(--ink-3); border-bottom: 2px solid var(--ink-3); transform: rotate(45deg); transition: transform .15s; flex: none; }
.cro-les[open] > summary::after { transform: rotate(-135deg); }
.cro-les > summary:hover .cro-les-title { color: var(--ink); }
.cro-les-title { flex: 1; min-width: 0; display: flex; align-items: center; gap: 8px; font-weight: 600; font-size: 15px; color: var(--ink-2); }
.cro-les-body { padding: 2px 20px 20px; }
.cro-les-body .cblk-list { margin-top: 6px; }
.cro-les-ov { color: var(--ink-2); margin: 0 0 12px; }
.cro-learn { margin: 0 0 14px 18px; color: var(--ink-2); }
.cro-learn li { margin-bottom: 5px; }
.cro-mats { display: grid; gap: 8px; margin-top: 14px; }
.cro-mat { display: flex; gap: 10px; align-items: flex-start; padding: 10px 12px; border: 1px solid var(--line); border-radius: 10px; font-size: 14px; }
.cro-mat svg { width: 17px; height: 17px; color: var(--ink-3); flex: none; margin-top: 2px; }
.adm-detail:not(.is-editing) .repeat-add,
.adm-detail:not(.is-editing) .repeat-del { display: none; }
.adm-detail:not(.is-editing) .edit-only { display: none; }
/* locked (view) fields = the SAME fields, just disabled: soft background, subtle (less-visible) border,
   readable text. Toggling to Edit only brightens the border + background — nothing shifts. */
.adm-detail:not(.is-editing) .course-fields input,
.adm-detail:not(.is-editing) .course-fields textarea,
.adm-detail:not(.is-editing) .course-fields select {
  background: var(--paper-2); border-color: var(--line); box-shadow: none; color: var(--ink); cursor: default; }
.adm-detail:not(.is-editing) .course-fields .checkrow { color: var(--ink-2); }
.adm-detail:not(.is-editing) .slug-edit { border-color: var(--line); background: var(--paper-2); }
/* copy-to-clipboard confirmation (share link) */
.copy-ok { align-self: center; color: var(--ok); font-size: 12.5px; font-weight: 600; opacity: 0; transition: opacity .2s; }
.copy-ok.show { opacity: 1; }
@media (max-width: 1180px) {
  .admin-main.admin-split { height: auto; overflow: visible; }
  .adm-split { grid-template-columns: 1fr; grid-template-rows: none; }
  .adm-list { max-height: 340px; }
}

/* ---------------- legal pages ---------------- */
.legal-wrap { display: grid; grid-template-columns: 200px minmax(0,1fr); gap: 48px; align-items: start; }
.legal-side { position: sticky; top: calc(var(--nav-h) + 24px); display: grid; gap: 2px; }
.legal-side-h { font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: .02em; color: var(--ink-3); margin-bottom: 6px; }
.legal-side a { font-size: 14.5px; color: var(--ink-2); padding: 6px 0; text-decoration: none; }
.legal-side a:hover { color: var(--ink); text-decoration: none; }
.legal-side a.on { color: var(--ink); font-weight: 600; }
.legal { max-width: 680px; }
.legal-note { background: var(--warn-wash); color: var(--warn); border-radius: var(--radius-sm); padding: 13px 16px;
  font-size: 13.5px; font-weight: 600; margin-bottom: 30px; }
.legal section { margin-bottom: 28px; }
.legal h2 { font-size: 1.3rem; margin-bottom: 10px; }
.legal p { color: var(--ink-2); line-height: 1.75; margin-bottom: 10px; }

/* ---------------- FAQ (distinct from curriculum accordion — plain question list) ---------------- */
.faq-list { display: grid; gap: 0; }
.faq-item { border-bottom: 1px solid var(--line); }
.faq-item:first-child { border-top: 1px solid var(--line); }
.faq-item summary { list-style: none; cursor: pointer; padding: 20px 36px 20px 0; font-size: 1.05rem; font-weight: 600;
  position: relative; color: var(--ink); }
.faq-item summary::-webkit-details-marker { display: none; }
.faq-item summary::after { content: ""; position: absolute; right: 2px; top: 50%; transform: translateY(-50%);
  width: 10px; height: 10px; border-right: 2px solid var(--ink-3); border-bottom: 2px solid var(--ink-3);
  transform-origin: center; }
.faq-item summary::after { transform: translateY(-70%) rotate(45deg); transition: transform .15s; }
.faq-item[open] summary::after { transform: translateY(-30%) rotate(-135deg); }
.faq-a { padding: 0 36px 22px 0; }
.faq-a p { color: var(--ink-2); line-height: 1.7; }

/* ---------------- nav (public) ---------------- */
/* explicit width:100% — without it, a flex/grid ancestor sizes .nav to its content's natural
   width instead of filling available space, silently clipping the nav-auth side. Latent bug,
   only visible once nav content got wide enough to exceed its container. */
.nav { position: sticky; top: 0; z-index: 50; width: 100%; height: var(--nav-h); background: rgba(255,255,255,.92);
  backdrop-filter: saturate(1.3) blur(10px); border-bottom: 1px solid var(--line); box-sizing: border-box; }
/* nav does NOT use .wrap — it gets its own full-bleed width + fixed 25px gutter, not the
   90%/1600px-cap centering every content section uses. Markup should be <div class="nav-in">,
   not <div class="wrap nav-in">.
   The brand lockup (.brand + .brand-sep + .brand-sub) sits together in one plain, unstyled div
   as the first child of .nav-in — not three separate flex items — so it moves as one unit:
   <div class="nav-in"><div><a class="brand">...</a><span class="brand-sep">|</span>
   <span class="brand-sub">Academy</span></div> ... nav-main ... nav-auth ... </div> */
.nav-in { display: flex; align-items: center; height: var(--nav-h); gap: 24px; width: 100%;
  padding: 0 25px; box-sizing: border-box; }
.brand { font-family: var(--font-serif); font-size: 26px; font-weight: 600; letter-spacing: -.01em; color: var(--ink);
  transition: color .15s; }
.brand span { color: var(--lime-text); }
.brand:hover { color: var(--lime-text); }
.brand-sep { display: inline-block; margin: 0 15px; color: var(--line-2); font-weight: 400; }
.brand-sub { font-family: var(--font-sans); font-size: .8em; font-weight: 600; color: var(--lime-text);
  letter-spacing: .03em; vertical-align: middle; }
.footer .brand-sep { color: var(--lime); }
.footer .brand-sub { color: var(--lime); }
.nav-main { display: flex; gap: 36px; margin-left: 80px; }
.nav-main a { font-size: 15.5px; font-weight: 600; color: var(--ink-2); position: relative; padding: 4px 0;
  text-decoration: none; }
.nav-main a:hover { color: var(--ink); text-decoration: none; }
/* selection = sketch underline only, never a text color change */
.nav-main a.on { color: var(--ink); }
.nav-main a.on::after { content: ""; position: absolute; left: 0; right: 2px; bottom: 0; height: 6px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 10' preserveAspectRatio='none'%3E%3Cpath d='M2,6 C15,2 25,8 40,4 C55,1 65,8 78,3 C88,0 94,6 98,4' fill='none' stroke='%23d5fc28' stroke-width='7' stroke-linecap='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-size: 100% 100%; }
.nav-auth { margin-left: auto; display: flex; align-items: center; gap: 20px; }
.nav-signin { font-size: 15.5px; font-weight: 600; color: var(--ink); }
.nav-burger { display: none; margin-left: auto; background: none; border: 1px solid var(--line-2);
  border-radius: var(--radius-sm); padding: 9px 10px; cursor: pointer; }
.nav-burger span { display: block; width: 20px; height: 2px; background: var(--ink); margin: 4px 0; }
.nav-m-only, .nav-m-sep { display: none; }   /* only shown inside the open mobile burger menu */

/* Archive nav dropdown: hover "Archive" to reveal "Selected Work" (opens the archived portfolio in a new
   tab). Umbrella nav only; "Archive" itself is a hover label, not a link, by design. */
.nav-drop-wrap { position: relative; display: inline-block; }
.nav-drop-top { font-size: 15.5px; font-weight: 600; color: var(--ink-2); padding: 4px 0; cursor: default; }
.nav-drop-wrap:hover .nav-drop-top { color: var(--ink); }
.nav-drop { display: none; position: absolute; top: calc(100% + 10px); left: 0; background: #fff;
  border: 1px solid var(--line); border-radius: 10px; padding: 6px; min-width: 150px;
  box-shadow: 0 10px 28px rgba(13,15,20,.10); z-index: 60; }
.nav-drop a { display: block; padding: 8px 12px; font-size: 15px; font-weight: 600; color: var(--ink-2);
  border-radius: 7px; text-decoration: none; }
.nav-drop a:hover { color: var(--ink); background: var(--accent-wash); }
.nav-drop-wrap:hover .nav-drop, .nav-drop-wrap:focus-within .nav-drop { display: block; }

/* acct / tab nav */
.acct-tabs { display: flex; gap: 4px; flex-wrap: wrap; border-bottom: 1px solid var(--line); }
.acct-tabs a { padding: 12px 4px 15px; margin-right: 24px; font-weight: 600; font-size: 15px; color: var(--ink-3);
  text-decoration: none; position: relative; margin-bottom: -1px; }
.acct-tabs a:hover { color: var(--ink); text-decoration: none; }
.acct-tabs a.on { color: var(--ink); }
.acct-tabs a.on::after { content: ""; position: absolute; left: 0; right: 6px; bottom: 1px; height: 5px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 10' preserveAspectRatio='none'%3E%3Cpath d='M2,6 C15,2 25,8 40,4 C55,1 65,8 78,3 C88,0 94,6 98,4' fill='none' stroke='%23d5fc28' stroke-width='7' stroke-linecap='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-size: 100% 100%; }

/* breadcrumbs */
.crumbs { display: flex; align-items: center; gap: 8px; font-size: 14px; color: var(--ink-3); flex-wrap: wrap; }
.crumbs a { color: var(--ink-3); }
.crumbs a:hover { color: var(--lime-text); }
.crumbs .sep { color: var(--line-2); }
.crumbs .here { color: var(--ink); font-weight: 600; }

/* admin sidebar */
.admin { display: grid; grid-template-columns: 244px minmax(0, 1fr); min-height: 100vh; }
.admin-side { background: var(--surface); border-right: 1px solid var(--line); padding: 22px 16px;
  position: sticky; top: 0; height: 100vh; display: flex; flex-direction: column; }
.admin-side .brand { font-size: 22px; padding: 0 8px 22px; }
.admin-nav { display: grid; gap: 2px; }
.admin-nav a { display: flex; align-items: center; gap: 12px; padding: 10px 12px; border-radius: var(--radius-sm);
  font-weight: 600; font-size: 14.5px; color: var(--ink-2); }
.admin-nav a:hover { background: var(--paper-2); color: var(--ink); text-decoration: none; }
.admin-nav a.on { background: var(--lime-wash); color: var(--lime-text); }
.admin-nav .ic { width: 18px; height: 18px; }
.admin-side-foot { margin-top: auto; display: grid; gap: 2px; padding-top: 14px; border-top: 1px solid var(--line); }
.admin-side-foot a { display: flex; align-items: center; gap: 10px; padding: 9px 12px; border-radius: var(--radius-sm); font-size: 13.5px; font-weight: 600; color: var(--ink-3); }
.admin-side-foot a:hover { background: var(--paper-2); color: var(--ink); text-decoration: none; }
.admin-side-foot .ic { width: 16px; height: 16px; flex: none; }
.admin-main { padding: 28px 34px 64px; min-width: 0; }
/* admin sidebar brand: "Alamly | Admin" like the public "Alamly | Academy" (only Alamly is the link) */
.admin-side .side-brand { display: flex; align-items: baseline; gap: 8px; padding: 0 8px 20px; }
.admin-side .side-brand .brand { font-size: 22px; padding: 0; }

/* ---- signed-in portal: full-width top nav + left sidebar + main (mirrors the admin sidebar) ---- */
.portal { display: grid; grid-template-columns: 260px minmax(0, 1fr); }
.portal-side { background: var(--surface); border-right: 1px solid var(--line); padding: 16px 14px;
  position: sticky; top: var(--nav-h); height: calc(100vh - var(--nav-h)); display: flex; flex-direction: column; }
.portal-welcome { flex: none; padding: 12px 12px 16px; border-bottom: 1px solid var(--line); margin-bottom: 12px; }
.portal-welcome .pw-hi { display: block; font-size: 12.5px; color: var(--ink-3); letter-spacing: .01em; margin-bottom: 3px; }
.portal-welcome .pw-name { display: block; font-family: var(--font-serif); font-size: 1.2rem; font-weight: 600;
  color: var(--ink); line-height: 1.2; letter-spacing: -.01em; }
.portal-nav { flex: 1; min-height: 0; overflow-y: auto; display: grid; gap: 2px; align-content: start; }
.portal-nav a { display: flex; align-items: center; gap: 12px; padding: 10px 12px; border-radius: var(--radius-sm);
  font-weight: 600; font-size: 14.5px; color: var(--ink-2); }
.portal-nav a:hover { background: var(--paper-2); color: var(--ink); text-decoration: none; }
.portal-nav a.on { background: var(--lime-wash); color: var(--lime-text); }
.portal-nav a svg { width: 18px; height: 18px; flex: none; }
.portal-foot { flex: none; padding-top: 12px; border-top: 1px solid var(--line); }
.portal-foot a { display: flex; align-items: center; gap: 10px; padding: 9px 12px; border-radius: var(--radius-sm);
  font-size: 13.5px; font-weight: 600; color: var(--ink-3); }
.portal-foot a:hover { background: var(--paper-2); color: var(--ink); text-decoration: none; }
.portal-foot a svg { width: 16px; height: 16px; flex: none; }
.portal-foot .pf-copy { margin: 8px 0 0; padding: 10px 12px 0; border-top: 1px solid var(--line);
  font-size: 12px; color: var(--ink-3); }
.portal-main { padding: 30px 36px 48px; min-width: 0; }
/* app pages use .wrap (viewport-based) — inside the portal column it must be full width of the column */
.portal-main .wrap { width: 100%; max-width: none; padding: 0; }
.portal-main .wrap.narrow { max-width: 760px; }
/* portal pages are content pages, not marketing heroes -> content type scale */
.portal-main h1 { font-size: clamp(1.7rem, 2.8vw, 2.2rem); }
/* ---- Behind-the-wall layout rhythm (user portal + admin), approved 2026-09-02. Spacing hierarchy +
   type/colour waterfall, scoped to .portal-main / .admin-main so public/marketing pages keep their own
   design. Page title small + no sub; groups separated by SPACE not boxes; tight label->field; big gaps
   between groups; heading (ink) > label (ink-2) > hint/value (ink-3). Device cards (.sess-item) keep
   their own card style on purpose. ---- */
.portal-main .pagehead { padding: 0 0 10px; margin: 0 0 50px; }
.portal-main .pagehead h1 { font-size: 1rem; font-weight: 700; line-height: 1.3; margin-bottom: 0; letter-spacing: 0; }
.portal-main .pagehead .sub { display: none; }
.admin-main .admin-top { margin-bottom: 44px; }
.admin-main .admin-top h1 { font-size: 1.25rem; }
.portal-main .set-block, .admin-main .set-block { border: none; padding: 0; margin-bottom: 48px; }
.portal-main .set-block:last-child, .admin-main .set-block:last-child { margin-bottom: 0; }
.portal-main .set-block h2, .admin-main .set-block h2 { font-size: 1.2rem; margin-bottom: 6px; }
.portal-main .set-block > .hint, .admin-main .set-block > .hint { margin: 0 0 24px; font-size: 14px; color: var(--ink-3); line-height: 1.6; max-width: 64ch; }
.portal-main .field, .admin-main .field { margin-bottom: 22px; }
.portal-main .field label, .admin-main .field label { font-size: 13.5px; color: var(--ink-2); margin-bottom: 7px; }
.portal-main .grid2, .admin-main .grid2 { gap: 22px; }
.portal-main .section-sm, .portal-main .section { padding: 0; }
.portal-footbar { display: flex; justify-content: space-between; gap: 16px; flex-wrap: wrap; margin-top: 44px;
  padding-top: 18px; border-top: 1px solid var(--line); font-size: 13px; color: var(--ink-3); }
.portal-footbar a { color: var(--ink-3); font-weight: 600; }
.portal-footbar a:hover { color: var(--ink); }
/* portal event list (app/events.php) */
.ev-list { display: grid; }
.ev-item { display: flex; justify-content: space-between; align-items: center; gap: 16px; padding: 14px 0; }
.ev-item + .ev-item { border-top: 1px solid var(--line); }
.ev-item-main { display: grid; gap: 3px; min-width: 0; }
.ev-item-main b { color: var(--ink); }
.ev-item-act { display: flex; align-items: center; gap: 12px; flex: none; }
.tag-muted { background: var(--paper-2); color: var(--ink-3); }
@media (max-width: 900px) {
  .portal { grid-template-columns: 1fr; }
  .portal-side { position: fixed; top: var(--nav-h); left: 0; bottom: 0; width: 262px; z-index: 120;
    transform: translateX(-100%); transition: transform .2s ease; box-shadow: var(--shadow-md); height: auto; }
  .portal-side.open { transform: none; }
  .portal-main { padding: 22px 18px 40px; }
}

/* ---------------- progress ---------------- */
.prog { height: 8px; border-radius: 6px; background: var(--line); overflow: hidden; }
.prog.sm { max-width: 120px; }   /* constrained progress bar inside a table cell */
.prog span { display: block; height: 100%; background: var(--lime); border-radius: 6px; transition: width .3s; }
.prog-label { display: flex; justify-content: space-between; font-size: 13px; color: var(--ink-3); margin-bottom: 8px; }

/* stepper (sequential lesson unlock states) */
.stepper { display: flex; flex-direction: column; gap: 2px; }
.step-item { display: flex; align-items: center; gap: 12px; padding: 10px 12px; border-radius: var(--radius-sm); font-size: 14.5px; }
.step-item .dot { width: 24px; height: 24px; border-radius: 50%; flex: none; display: grid; place-items: center; }
.step-item .dot svg { width: 13px; height: 13px; }
.step-item.done { color: var(--ink-2); }
.step-item.done .dot { background: var(--ok-vivid); color: #fff; }
.step-item.current { background: var(--lime-wash); color: var(--ink); font-weight: 600; }
.step-item.current .dot { background: var(--lime); color: var(--ink); }
.step-item.locked { color: var(--ink-3); }
.step-item.locked .dot { background: var(--paper-2); color: var(--ink-3); border: 1.5px solid var(--line); }

/* avatar — the ONE circular person-image component, used everywhere (admin chip, mini-list,
   instructor card, checkout, anywhere a person appears). Content is either an <img> or bare
   initials text as a fallback — same element, same size, same rule everywhere; nothing else
   in the system should invent its own person-circle. */
.avatar { width: 55px; height: 55px; border-radius: 50%; background: var(--lime-wash); color: var(--lime-text);
  display: grid; place-items: center; font-weight: 700; font-size: 18px; letter-spacing: .02em;
  flex: none; overflow: hidden; }
.avatar img { width: 100%; height: 100%; object-fit: cover; }
.avatar.sm { width: 36px; height: 36px; font-size: 13px; }
.avatar.lg { width: 72px; height: 72px; font-size: 22px; }

/* person row: avatar + name/subtitle stack + trailing status, vertically centered as one unit */
.person-row { display: flex; align-items: center; gap: 14px; }
.person-row .who { display: grid; gap: 5px; min-width: 0; }
.person-row .who b { font-size: 14.5px; color: var(--ink); font-weight: 600; }
.person-row .who span { font-size: 13px; color: var(--ink-3); }
.person-row .status { margin-left: auto; flex: none; }

/* ---------------- tables ---------------- */
.ptable { border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden; background: var(--surface); }
.ptable-row { display: grid; grid-template-columns: 2fr 1fr 1fr 1fr auto; gap: 18px; align-items: center;
  padding: 15px 20px; border-top: 1px solid var(--line); }
.ptable-row:first-child { border-top: none; }
.ptable-head { background: var(--paper-2); font-size: 12px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .02em; color: var(--ink-3); }
.ptable-row span { font-size: 14.5px; color: var(--ink-2); }
.ptable-row b { color: var(--ink); }
.ptable-rules .ptable-row { grid-template-columns: 1.3fr 1.1fr 1.8fr; align-items: start; padding-top: 16px; padding-bottom: 16px; }
.ptable-rules .ptable-row span { line-height: 1.5; }

/* ---------------- alert banners (inline, on-page) ---------------- */
.alert { display: flex; gap: 14px; align-items: flex-start; padding: 16px 18px; border-radius: var(--radius);
  font-size: 14.5px; line-height: 1.5; }
.alert .ic { width: 20px; height: 20px; flex: none; margin-top: 1px; }
.alert b { display: block; color: inherit; margin-bottom: 2px; }
.alert-ok    { background: var(--ok-wash); color: var(--ok); }
.alert-ok .ic { color: var(--ok-vivid); }
.alert-warn  { background: var(--warn-wash); color: var(--warn); }
.alert-warn .ic { color: var(--warn-vivid); }
.alert-err   { background: var(--err-wash); color: var(--err); }
.alert-info  { background: var(--info-wash); color: var(--info); }
.alert-close { margin-left: auto; background: none; border: none; cursor: pointer; color: inherit; opacity: .6; padding: 0; }
.alert-close:hover { opacity: 1; }

/* ---------------- toasts (JS-driven, see main.js) ---------------- */
.toast-stack { position: fixed; top: 20px; right: 20px; z-index: 200; display: flex; flex-direction: column;
  gap: 10px; max-width: 360px; width: calc(100% - 40px); }
.toast { display: flex; align-items: flex-start; gap: 12px; padding: 14px 16px; border-radius: var(--radius);
  background: var(--ink); color: #fff; box-shadow: var(--shadow-md); font-size: 14.5px; font-weight: 500;
  opacity: 0; transform: translateY(-8px); transition: opacity .2s, transform .2s; }
.toast.in { opacity: 1; transform: translateY(0); }
.toast-ic { flex: none; width: 20px; height: 20px; margin-top: 1px; }
.toast-msg { flex: 1; }
.toast-close { background: none; border: none; color: rgba(255,255,255,.6); cursor: pointer; font-size: 18px;
  line-height: 1; padding: 0; flex: none; }
.toast-close:hover { color: #fff; }
.toast-success .toast-ic { color: var(--lime); }
.toast-error   .toast-ic { color: #ff8a80; }
.toast-warning .toast-ic { color: #ffd166; }
.toast-info    .toast-ic { color: var(--lime); }

/* ---------------- modal ---------------- */
.modal { position: fixed; inset: 0; z-index: 300; display: none; align-items: flex-start; justify-content: center;
  padding: 24px; overflow-y: auto; }
.modal.open { display: flex; }
.modal-backdrop { position: fixed; inset: 0; background: rgba(26,26,26,.5); }
/* margin:auto centers the box when it fits, and anchors it to the top (scrollable) when it is taller
   than the viewport, so the close button and the top of a long form are always reachable. */
.modal-box { position: relative; background: var(--surface); border-radius: var(--radius-lg); padding: 32px;
  max-width: 460px; width: 100%; box-shadow: var(--shadow-md); margin: auto; }
.modal-box h3 { margin-bottom: 10px; }
.modal-box p { margin-bottom: 22px; }
.modal-close { position: absolute; top: 18px; right: 18px; background: none; border: none; cursor: pointer;
  color: var(--ink-3); padding: 4px; line-height: 0; }
/* The close SVG carries no width/height and no .ic class, so it collapses to 0x0 (invisible) without
   this. Size it here so every dismissible modal (auth popup, OTP popup, confirm dialogs) shows its X. */
.modal-close svg { width: 22px; height: 22px; display: block; }
.modal-close:hover { color: var(--ink); }
.modal-actions { display: flex; gap: 12px; justify-content: flex-end; flex-wrap: wrap; }
/* One or two actions sit in a row; a 3rd won't fit a 460px row without the first button spilling out
   of the box, so once there's a 3rd .btn we stack them all full-width in priority order. This keeps the
   readable body width (no fit-content stretch) and leaves every 1-2 button modal unchanged. */
.modal-actions:has(> .btn:nth-child(3)) { flex-direction: column; align-items: stretch; }
.modal-actions:has(> .btn:nth-child(3)) .btn { width: 100%; }
/* modal edge cases (were missing): three sizes instead of one fixed 460, a title+close header row
   that aligns instead of an absolutely-positioned close over the corner, and a scroll variant so a
   long body scrolls INSIDE the card (header + actions stay put) instead of the whole card
   overflowing the viewport. Opt-in — the base modal is unchanged. */
.modal-box.sm { max-width: 380px; }
.modal-box.lg { max-width: 640px; }
.modal-head { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--sp-2);
  margin-bottom: var(--sp-2); }
.modal-head .modal-close { position: static; top: auto; right: auto; }
.modal-box.scroll { display: flex; flex-direction: column; max-height: calc(100vh - var(--sp-6)); }
.modal-box.scroll .modal-body { overflow-y: auto; margin: 0 -8px; padding: 0 8px; }

/* ---- guided enquiry chat: a docked bottom-right widget (Consulting now, site-wide "Need Help?" next) ----
   Three states toggled by nsEnquiryChat() in main.js via data-state: a round launcher, an open panel, or
   a minimized bar. The panel is a small chat: fixed header (minimize + close), a scrolling message log,
   and an input dock that swaps between a text field, a message box, and choice buttons as the flow
   (includes/enquiry-flow.php) walks. Posts to /enquiry.php. Bubbles: .bot (Alam, left) / .you (right). */
.enq-dock { position: fixed; right: 20px; bottom: 20px; z-index: 200; }
.enq-launcher, .enq-minbar, .enq-panel { position: fixed; right: 20px; bottom: 20px; z-index: 200; }
.enq-dock [hidden], .enq-launcher[hidden], .enq-minbar[hidden], .enq-panel[hidden] { display: none !important; }   /* class display beats the bare hidden attr, so force it for every hidden part */
.enq-launcher { width: 60px; height: 60px; border-radius: 50%; background: var(--lime); color: var(--ink);
  border: none; cursor: pointer; box-shadow: var(--shadow-md); display: grid; place-items: center; transition: background .15s, transform .15s; }
.enq-launcher:hover { background: var(--lime-hover); transform: translateY(-2px); }
.enq-launcher svg { width: 27px; height: 27px; }
.enq-minbar { display: flex; align-items: center; gap: 10px; background: var(--surface); color: var(--ink);
  border: 1px solid var(--line); border-radius: 999px; padding: 8px 16px 8px 8px; box-shadow: var(--shadow-md);
  cursor: pointer; font: inherit; }
.enq-minbar b { font-size: 14.5px; font-weight: 700; }
.enq-minbar .enq-chev { width: 18px; height: 18px; color: var(--ink-3); }
.enq-avatar.sm { width: 34px; height: 34px; font-size: 13px; }
.enq-panel { width: 384px; height: min(600px, calc(100vh - 40px)); background: var(--surface);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-md); display: flex; flex-direction: column;
  overflow: hidden; animation: enqUp .24s ease; }
@keyframes enqUp { from { opacity: 0; transform: translateY(16px); } to { opacity: 1; transform: none; } }
.enq-head { display: flex; align-items: center; gap: 12px; padding: 16px 14px 16px 20px;
  border-bottom: 1px solid var(--line); flex: none; }
.enq-who { flex: 1 1 auto; }
.enq-head-btns { display: flex; gap: 2px; }
.enq-hbtn { background: none; border: none; cursor: pointer; color: var(--ink-3); padding: 6px; line-height: 0;
  border-radius: var(--radius-sm); }
.enq-hbtn:hover { color: var(--ink); background: var(--paper-2); }
.enq-hbtn svg { width: 20px; height: 20px; display: block; }
.enq-confirm { position: absolute; inset: 0; background: var(--surface); display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 18px; padding: 28px; text-align: center; z-index: 3; }
.enq-confirm p { margin: 0; font-size: 15.5px; color: var(--ink-2); max-width: 260px; line-height: 1.5; }
.enq-confirm-btns { display: flex; gap: 10px; }
@media (max-width: 480px) {
  .enq-panel { right: 0; bottom: 0; width: 100%; height: 100%; border-radius: 0; }
  .enq-launcher, .enq-minbar, .enq-dock { right: 16px; bottom: 16px; }
}
.enq-avatar { width: 42px; height: 42px; border-radius: 50%; background: var(--lime); color: var(--ink);
  display: grid; place-items: center; font-weight: 800; font-size: 15px; flex: none; }
.enq-who { display: flex; flex-direction: column; line-height: 1.3; }
.enq-who b { font-weight: 700; font-size: 15.5px; }
.enq-who span { color: var(--ink-3); font-size: 13px; }
.enq-log { flex: 1 1 auto; overflow-y: auto; padding: 20px 22px; display: flex; flex-direction: column;
  gap: 12px; background: var(--paper); }
.enq-msg { max-width: 84%; padding: 11px 15px; border-radius: 16px; font-size: 15.5px; line-height: 1.55;
  white-space: pre-wrap; overflow-wrap: anywhere; animation: enqIn .22s ease; }
.enq-msg.bot { align-self: flex-start; background: var(--surface); color: var(--ink);
  border: 1px solid var(--line); border-bottom-left-radius: 5px; }
.enq-msg.you { align-self: flex-end; background: var(--ink); color: #fff; border-bottom-right-radius: 5px; }
@keyframes enqIn { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
.enq-typing { align-self: flex-start; display: inline-flex; gap: 4px; padding: 14px 16px; }
.enq-typing i { width: 7px; height: 7px; border-radius: 50%; background: var(--ink-3);
  animation: enqDot 1s infinite ease-in-out; }
.enq-typing i:nth-child(2) { animation-delay: .15s; }
.enq-typing i:nth-child(3) { animation-delay: .3s; }
@keyframes enqDot { 0%, 60%, 100% { transform: translateY(0); opacity: .35; } 30% { transform: translateY(-4px); opacity: .9; } }
.enq-input { flex: none; position: relative; border-top: 1px solid var(--line); padding: 14px 16px; background: var(--surface); }
.enq-input:empty { display: none; }
.enq-ts { flex: none; padding: 12px 16px; display: flex; justify-content: center; background: var(--surface); }

/* ---- admin "Chat setup" editor (bak34759in/enquiry-config.php); built + serialized in main.js ---- */
.ec-editor { display: flex; flex-direction: column; gap: 22px; margin-bottom: 96px; }
.ec-2col { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; }
.ec-note { color: var(--ink-3); font-size: 14px; margin: -4px 0 16px; }
.ec-step { border: 1px solid var(--line); border-radius: var(--radius); padding: 16px 16px 4px; background: var(--paper); margin-bottom: 14px; }
.ec-step-head { display: flex; align-items: center; gap: 10px; margin-bottom: 14px; }
.ec-step-head b { font-size: 14px; font-weight: 700; }
.ec-step-tag { font-size: 12px; font-weight: 700; color: var(--lime-text); background: var(--lime-wash); padding: 2px 8px; border-radius: 20px; }
.ec-step-actions { margin-left: auto; display: flex; gap: 6px; }
.ec-iconbtn { background: none; border: 1px solid var(--line-2); border-radius: var(--radius-sm); width: 30px; height: 30px; display: grid; place-items: center; cursor: pointer; color: var(--ink-2); }
.ec-iconbtn:hover:not(:disabled) { border-color: var(--ink); color: var(--ink); }
.ec-iconbtn:disabled { opacity: .35; cursor: default; }
.ec-iconbtn svg { width: 16px; height: 16px; }
.ec-flags { display: flex; flex-wrap: wrap; gap: 18px; margin-bottom: var(--sp-25); }
.ec-flags label { display: inline-flex; align-items: center; gap: 7px; font-size: 14px; font-weight: 600; cursor: pointer; }
.ec-flags input { width: auto; }
.ec-opt-row { display: flex; gap: 8px; margin-bottom: 8px; }
.ec-opt-row input { flex: 1; }
.ec-opt-row .ec-opt-key { flex: 0 0 160px; max-width: 160px; }   /* the short menu-item key next to its label */
.ec-choice-label { display: block; font-size: var(--text-md); font-weight: 600; margin-bottom: 8px; }
@media (max-width: 720px) { .ec-2col { grid-template-columns: 1fr; } }
.enq-field { display: flex; gap: 10px; align-items: flex-end; }
.enq-field input, .enq-field textarea { flex: 1 1 auto; width: 100%; border: 1.5px solid var(--line-2);
  border-radius: var(--radius-sm); padding: var(--sp-15) var(--sp-2); font-size: var(--text-lg);
  font-family: inherit; color: var(--ink); background: var(--surface);
  transition: border-color .15s, box-shadow .15s; }
.enq-field textarea { min-height: 48px; max-height: 150px; resize: vertical; }
.enq-field input:focus, .enq-field textarea:focus { outline: none; border-color: var(--ink);
  box-shadow: 0 0 0 3px var(--lime-wash); }
.enq-send { flex: none; }
.enq-choices { display: flex; flex-wrap: wrap; gap: 8px; }
.enq-choices .btn { text-align: left; }
.enq-alt { display: inline-block; background: none; border: none; color: var(--lime-text); font: inherit;
  font-size: 13.5px; cursor: pointer; padding: 2px 0; margin-top: 12px; text-decoration: underline; }
/* title picker: suggestions float UPWARD from the field (it sits near the panel bottom), over the log */
.enq-suggest { position: absolute; left: 16px; right: 16px; bottom: 100%; margin-bottom: 8px;
  display: flex; flex-direction: column; gap: 4px; max-height: 240px; overflow-y: auto;
  background: var(--surface); border: 1px solid var(--line-2); border-radius: var(--radius);
  box-shadow: var(--shadow-md); padding: 6px; z-index: 5; }
.enq-suggest:empty { display: none; }
.enq-suggest-item { text-align: left; background: none; border: none; border-radius: var(--radius-sm);
  padding: 10px 12px; font: inherit; font-size: 14.5px; color: var(--ink); cursor: pointer; }
.enq-suggest-item:hover { background: var(--lime-wash); }
.enq-suggest-none { color: var(--ink-3); font-size: 13.5px; padding: 8px 10px; }
/* "change" link shown under a chosen category */
.enq-change-row { align-self: flex-end; margin-top: -6px; }
.enq-change { background: none; border: none; color: var(--ink-3); font: inherit; font-size: 12.5px; cursor: pointer;
  text-decoration: underline; padding: 0; }
.enq-change:hover { color: var(--ink); }
@media (max-width: 560px) { .enq-choices .btn { width: 100%; } }

/* ---- shared auth modal: one modal, swappable panes (sign in / sign up / forgot / sent) ----
   Only one .auth-pane is visible at a time; switching fades the new one in so it feels like the
   same card changing, not a reload. Reuses .modal / .modal-box / .field / .btn as-is. */
.auth-box { max-width: 600px; }
.auth-pane { display: none; }
.auth-pane.on { display: block; animation: authFade .18s ease; }
@keyframes authFade { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }
.auth-pane h3 { margin-bottom: 6px; }
.auth-pane .auth-sub { color: var(--ink-3); font-size: 15px; margin-bottom: 20px; }
.auth-pane .field { margin-bottom: 16px; }
.auth-pane .btn-block { margin-top: 4px; }
/* the "switch pane" links (Create an account / Sign in / Forgot password) */
.auth-alt { margin-top: 18px; font-size: 15px; color: var(--ink-3); text-align: center; }
.auth-alt button { background: none; border: none; padding: 0; cursor: pointer; font: inherit;
  color: var(--lime-text); font-weight: 600; }
.auth-alt button:hover { opacity: .8; text-decoration: underline; }
.auth-forgot { text-align: right; margin-top: -8px; margin-bottom: 16px; }
.auth-forgot button { background: none; border: none; padding: 0; cursor: pointer; font: inherit;
  font-size: 14px; color: var(--lime-text); font-weight: 600; }
.auth-forgot button:hover { opacity: .8; text-decoration: underline; }
/* success pane (reset link sent / account created) reuses the result look, compact */
.auth-pane .auth-done { text-align: center; padding: 8px 0 4px; }
.auth-pane .auth-done .result-icon { margin: 0 auto 16px; }
/* type-only confirm fields: a tiny shake if paste/drop is blocked, so the block is felt not silent */
input.shake { animation: nsShake .35s ease; }
@keyframes nsShake { 0%,100%{transform:none} 20%,60%{transform:translateX(-4px)} 40%,80%{transform:translateX(4px)} }
/* inline error / notice lines inside an auth pane */
.auth-error { color: var(--err); font-size: 14px; margin: -2px 0 12px; }
.auth-notice { color: var(--lime-text); font-size: 14px; margin: -2px 0 12px; }
/* the "wrong email? change it" disclosure inside the verify pane */
.auth-change { margin-top: 18px; border-top: 1px solid var(--line); padding-top: 14px; }
.auth-change summary { cursor: pointer; font-size: 14px; color: var(--lime-text); font-weight: 600; list-style: none; }
.auth-change summary::-webkit-details-marker { display: none; }
.auth-change-form { margin-top: 14px; }
/* Sign in / Sign up in the nav are <button>s now (they open the popup), not links — normalize them */
button.nav-signin { background: none; border: 0; cursor: pointer; font: inherit; font-size: 15.5px; font-weight: 600; color: var(--ink); }
button.nav-signin:hover { color: var(--lime-text); }

/* ---- progressive profile nudge (one field at a time on the dashboard) ---- */
.pnudge { display: flex; align-items: flex-start; gap: 14px; background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 16px 18px; margin-bottom: var(--sp-4); position: relative; }
.pnudge[hidden] { display: none; }   /* respect the hidden attribute (display:flex would override it) */
.pnudge-ic { width: 36px; height: 36px; border-radius: 50%; background: var(--lime-wash); color: var(--lime-text);
  display: grid; place-items: center; flex: none; }
.pnudge-ic svg { width: 18px; height: 18px; }
.pnudge-main { flex: 1; min-width: 0; }
.pnudge-q { display: block; color: var(--ink); margin-bottom: 10px; font-size: 15.5px; }
.pnudge-form { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; }
.pnudge-close { position: absolute; top: 10px; right: 10px; background: none; border: none; cursor: pointer;
  color: var(--ink-3); padding: 4px; }
.pnudge-close:hover { color: var(--ink); }
.pnudge-close svg { width: 16px; height: 16px; }
.pnudge-done { color: var(--lime-text); font-weight: 600; display: flex; align-items: center; gap: 8px; }
.pnudge-done svg { width: 18px; height: 18px; }
/* inline form control: same look as a .field input, sized to sit in a row (nudge + quick forms) */
.field-inline { padding: 10px 14px; border: 1px solid var(--line); border-radius: 10px; font: inherit; font-size: 15px;
  background-color: var(--surface); color: var(--ink); min-width: 210px; }
.field-inline:focus { outline: none; border-color: var(--lime); }
/* profile completion meter row */
.prof-meter-row { display: flex; align-items: center; gap: 16px; }
.prof-meter-row > span { font-weight: 600; color: var(--ink); white-space: nowrap; }
.prof-meter-row .prog { flex: 1; }

/* ---- print: for invoices, hide the site chrome and show only the document ("Save as PDF") ---- */
@media print {
  .nav, .footer, .nav-burger, .acct-tabs, .no-print { display: none !important; }
  body { background: #fff; }
  .section-sm { padding: 0 !important; }
  .wrap.narrow { width: 100%; max-width: none; }
  .invoice { border: none !important; box-shadow: none !important; margin: 0; padding: 0; }
}

/* ---- accessibility: a clear keyboard-focus ring on interactive elements (only on keyboard nav,
   never on mouse click, thanks to :focus-visible). Form fields already signal focus via border. ---- */
a:focus-visible, button:focus-visible, .btn:focus-visible, summary:focus-visible,
.acct-btn:focus-visible, .modal-close:focus-visible, .nav-main a:focus-visible,
.linkbtn:focus-visible, [tabindex]:focus-visible, [role="button"]:focus-visible {
  outline: 2px solid var(--lime-text); outline-offset: 2px; border-radius: 3px;
}
/* honour reduced-motion for the animations added in the auth/nudge/loader work */
@media (prefers-reduced-motion: reduce) {
  .auth-pane.on, .acct .acct-pop, .pnudge, input.shake, .toast { animation: none !important; }
  html { scroll-behavior: auto; }
}

/* ---- cookie consent bar (bottom, non-blocking; shown until a choice is stored) ---- */
.cookie-bar { position: fixed; left: 50%; transform: translateX(-50%); bottom: 16px; z-index: 350;
  width: min(920px, calc(100% - 32px)); background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius); box-shadow: var(--shadow-md); padding: 16px 20px;
  display: flex; align-items: center; gap: 18px; }
.cookie-bar[hidden] { display: none; }   /* respect the hidden attribute (display:flex would override it) */
.cookie-bar .cookie-text { margin: 0; font-size: 14.5px; color: var(--ink-2); flex: 1; }
.cookie-bar .cookie-text a { color: var(--lime-text); font-weight: 600; }
.cookie-acts { display: flex; gap: 10px; flex: none; }
/* Turnstile widget spacing inside forms */
.ts-widget { margin: 4px 0 16px; }
@media (max-width: 640px) { .cookie-bar { flex-direction: column; align-items: stretch; text-align: left; }
  .cookie-acts { justify-content: flex-end; } }
@media print { .cookie-bar { display: none !important; } }

/* ---- account menu: avatar button + dropdown (shown in the header when signed in) ----
   Replaces the Sign in / Sign up pair once a user is signed in. Reuses .avatar for the circle. */
.acct { position: relative; margin-left: 4px; }
.acct-btn { display: inline-flex; align-items: center; gap: 8px; background: none; border: none;
  cursor: pointer; padding: 2px; border-radius: 999px; }
.acct-btn .avatar { width: 40px; height: 40px; font-size: 14px; }
.acct-btn .chev { width: 16px; height: 16px; color: var(--ink-3); transition: transform .15s ease; }
.acct.open .acct-btn .chev { transform: rotate(180deg); }
.acct-pop { position: absolute; top: calc(100% + 10px); right: 0; min-width: 220px; background: var(--surface);
  border: 1px solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow-md); padding: 8px;
  display: none; z-index: 320; }
.acct.open .acct-pop { display: block; animation: authFade .16s ease; }
.acct-pop .acct-id { padding: 8px 12px 12px; border-bottom: 1px solid var(--line); margin-bottom: 6px; }
.acct-pop .acct-id b { display: block; color: var(--ink); font-size: 14.5px; }
.acct-pop .acct-id span { display: block; color: var(--ink-3); font-size: 13px; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; }
.acct-pop a, .acct-pop button.acct-link { display: flex; align-items: center; gap: 10px; width: 100%;
  padding: 9px 12px; border-radius: 9px; color: var(--ink-2); font-size: 14.5px; font-weight: 500;
  background: none; border: none; cursor: pointer; text-align: left; }
.acct-pop a:hover, .acct-pop button.acct-link:hover { background: var(--paper-2); color: var(--ink); }
.acct-pop a svg, .acct-pop button.acct-link svg { width: 17px; height: 17px; color: var(--ink-3); flex: none; }
.acct-pop .acct-sep { height: 1px; background: var(--line); margin: 6px 0; }

/* ---------------- empty state ---------------- */
.empty { text-align: center; padding: 64px 24px; background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius-lg); }
.empty .ic-chip { margin: 0 auto 20px; }
/* h3 margin-bottom now comes from the base rule (8px) */
.empty p { max-width: 40ch; margin: 0 auto 20px; }

/* ---------------- result (success / failure page) ---------------- */
.result { max-width: 560px; margin: 0 auto; text-align: center; }
.result h1 { margin-bottom: 12px; }
.result .btn-row { justify-content: center; }
.result-icon { width: 72px; height: 72px; border-radius: 50%; display: grid; place-items: center; margin: 0 auto 24px; }
.result-icon svg { width: 34px; height: 34px; }
.result-icon.ok  { background: var(--ok-wash); color: var(--ok-vivid); }
.result-icon.bad { background: var(--err-wash); color: var(--err); }
.result-icon.info { background: var(--warn-wash); color: var(--warn-vivid); }   /* amber: "not available / expired" */

/* ---------------- draft preview bar ----------------
   Full-width amber bar shown at the top of a DRAFT public page when an admin previews it (the public
   never sees the page at all). Shared by every content type with a draft/published status. */
.preview-bar { background: var(--warn-wash); color: var(--warn); text-align: center; padding: 11px 16px;
  font-size: 13.5px; font-weight: 600; border-bottom: 1px solid var(--warn-vivid); }
.preview-bar a { color: var(--warn-vivid); text-decoration: underline; margin-left: 6px; }
/* "unpublished changes" pill (extends .tag) — an item is published but has edits not yet made live */
.tag.tag-changes { background: var(--warn-wash); color: var(--warn-vivid); }

/* ---------------- dark band (where bright lime may be text) ---------------- */
/* reusable mid-page CTA band, independent of the footer */

/* ---------------- footer ----------------
   One merged dark section: waitlist CTA + brand/link columns + copyright bar all share
   the same #141414 surface, not three separate light/dark blocks. */
.footer { background: #141414; color: #c7c7c2; padding: 0; }
/* Footer is a bare wrapper; its two <section>s (newsletter + main) own the vertical rhythm, so the
   spacing stays consistent whether or not the newsletter section is rendered. The divider sits at the
   BOTTOM edge of the newsletter section (after its padding), and disappears with it when it's hidden. */
.footer-news { padding: var(--section-y) 0; border-bottom: 1px solid rgba(255,255,255,.12); }
.footer-main { padding: var(--section-y) 0 var(--sp-45); }
.footer-cta h2, .footer-cta h3 { color: #fff; }
.footer-cta p { color: #a7a7a0; }
/* Footer newsletter section is centered (home page spec). Center the copy, the email box and the note. */
.footer-cta { text-align: center; }
.footer-cta .capture { margin-inline: auto; margin-top: var(--sp-4); }
.footer-cta .btn-row { justify-content: center; }
.footer-cta .form-note { text-align: center; }
.footer-top { display: flex; justify-content: space-between; gap: 48px; flex-wrap: wrap; padding: 0 0 40px; }
.foot-brand { max-width: 320px; }
.foot-brand .brand { color: #fff; }
.foot-brand .brand span { color: var(--lime); }
.foot-brand .brand:hover { color: var(--lime); }
.foot-brand p { font-size: 14.5px; color: #8f8f89; margin-top: 10px; }
.footer-cols { display: flex; gap: 64px; flex-wrap: wrap; }
.footer-col h4 { font-family: var(--font-sans); font-size: 13.5px; font-weight: 700; color: #fff; margin-bottom: 14px; }
.footer-col a { display: block; padding: 5px 0; font-size: 15px; color: #a7a7a0; text-decoration: none; }
.footer-col a:hover { color: var(--lime); text-decoration: none; }
.footer-bottom { padding: 24px 0 0; border-top: 1px solid rgba(255,255,255,.12); font-size: 13.5px; color: #7a7a75;
  display: flex; justify-content: space-between; align-items: center; gap: 16px; flex-wrap: wrap; }
/* social sits under the brand description (foot-brand), matching the current site — not in the
   bottom bar */
.social { display: flex; gap: 12px; margin-top: 18px; }
.social a { width: 38px; height: 38px; border: 1px solid rgba(255,255,255,.16); border-radius: var(--radius-sm);
  display: grid; place-items: center; color: #a7a7a0; }
.social a:hover { color: var(--lime); border-color: var(--lime); }
.social svg { width: 18px; height: 18px; }

/* ---------------- style guide scaffold ----------------
   MOVED OUT to assets/css/styleguide.css (loaded only by styleguide.html), so real pages
   no longer download it. If you add a .sg-* rule, it goes in that file, not here. */

/* ---------------- home page ---------------- */
.measure-lg { max-width: 62ch; }

.hero { padding: var(--section-y) 0; }
.hero-grid { display: grid; grid-template-columns: minmax(0,1fr) 420px; gap: var(--sp-6); align-items: center; }
/* a content-light hero (e.g. About: short intro text + one photo) reads better in a tighter column
   than the 1600px page cap, so the text and image don't drift too far apart. */
.wrap.hero-narrow { max-width: 1100px; }
.hero h1 { margin-bottom: 22px; }
.hero .lead { max-width: none; margin-bottom: 32px; }
.hero .trust { margin-top: 22px; font-size: 14px; color: var(--ink-3); }

/* the credibility strip, sized down to sit inside the hero under the CTAs (no border, smaller) */
.trusted.mini { border: none; padding: 0; margin-top: var(--sp-5); gap: 10px 20px; }
.trusted.mini .l { font-size: 11px; }
.trusted.mini .logo-slot { font-size: 13px; }

/* northstar hero: a wider media column holding a 360px module carousel */
.hero-grid.media-lg { grid-template-columns: minmax(0,1fr) 600px; }
.hero-media .c-slide .frame { height: 360px; }   /* plain bordered frame (no browser chrome) */
.hero-photo { border-radius: var(--radius-lg); overflow: hidden; border: 1px solid var(--line);
  background: var(--paper-2); aspect-ratio: 4/5; }
/* object-position: top — keep the top of the portrait (head/face) visible and let any
   crop fall off the bottom instead of the default center-crop, which was cutting off the top */
.hero-photo { aspect-ratio: 5 / 5; }
.hero-photo img { width: 100%; height: 100%; object-fit: cover; object-position: top; }

.trusted { display: flex; align-items: center; gap: 28px; flex-wrap: wrap; padding: 28px 0;
  border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }
.trusted .l { font-size: 12.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .06em;
  color: var(--ink-3); flex: none; }
.trusted .logos { display: flex; gap: 28px 36px; flex-wrap: wrap; }
.trusted .logo-slot { font-family: var(--font-serif); font-size: 15px; font-weight: 600; color: var(--ink-3); }

.split { display: grid; grid-template-columns: minmax(0,1fr) minmax(0,1fr); gap: var(--sp-6); align-items: center; }
.split.top { align-items: start; }
.split.wide-right { grid-template-columns: minmax(0,1fr) minmax(0,1.5fr); }  /* wider right column (e.g. FAQ) */
.split .btn-row { margin-top: var(--sp-5); }

.shot { border: 1px solid var(--line); border-radius: var(--radius-lg); overflow: hidden;
  background: var(--surface); box-shadow: var(--shadow-sm); }
.shot .bar { display: flex; gap: 7px; padding: 14px 16px; border-bottom: 1px solid var(--line); }
.shot .bar i { width: 11px; height: 11px; border-radius: 50%; background: var(--line-2); display: block; }
.shot img { width: 100%; display: block; }
.shot .zoomshot { height: 340px; }   /* the home NorthStar shot is zoomable (natural-size, clipped) */

/* .topics / .startgrid / .quotes removed — those card rows now use the .grid.cols-N primitive
   directly in the markup. .gallery (framed screenshots + caption) stays, it's a real component. */
.topic { display: block; padding: 28px 26px; transition: border-color .15s, box-shadow .15s; }
.topic:hover { border-color: var(--line-2); box-shadow: var(--shadow-sm); text-decoration: none; }
.topic-ic { width: 46px; height: 46px; border-radius: var(--radius); background: var(--lime-wash);
  color: var(--lime-text); display: grid; place-items: center; margin-bottom: 18px; }
.topic-ic svg { width: 22px; height: 22px; }
/* h3 margin-bottom now comes from the base rule (8px) */
.topic p { font-size: 15px; margin-bottom: 18px; }
.topic-go { display: inline-flex; align-items: center; gap: 6px; font-size: 14px; font-weight: 700; color: var(--lime-text); }
.topic-go.arrow::after { content: "\2192"; transition: transform .15s; display: inline-block; }
.topic:hover .topic-go.arrow::after { transform: translateX(3px); }

.startcard { display: block; padding: 28px; transition: border-color .15s, box-shadow .15s; }
.startcard:hover { border-color: var(--line-2); box-shadow: var(--shadow-sm); text-decoration: none; }
.startcard-top { display: flex; justify-content: space-between; align-items: center; gap: 10px; margin-bottom: 18px; }
/* was 10px, the one outlier — now matches every other card title via the base rule (8px) */
.startcard p { font-size: 15px; margin-bottom: 18px; }
.section-cta { text-align: center; margin-top: 40px; }

/* skeleton (surface + hairline + radius-lg) comes from the shared content-card rule above;
   a notecard sits among marketing content, not a dashboard, so it is a content card, not a
   compact tile (.statcard / .admin-card, which use the smaller --radius). */
.notecard { padding: 22px 24px; }
.notecard .ic-chip { margin-bottom: 14px; }
.notecard p { font-size: 14.5px; }
/* Equal-height cards with bottom-aligned, content-width buttons: the grid stretches cards to equal
   height, the description grows so every button drops to the same baseline, and the button opts out of
   the flex-column stretch (align-self) so it keeps its natural content width. Opt-in per grid. */
.grid.cards-even .notecard { display: flex; flex-direction: column; }
.grid.cards-even .notecard p { flex-grow: 1; }
.grid.cards-even .notecard .btn { align-self: flex-start; }

.stats { display: flex; gap: var(--sp-5); flex-wrap: wrap; margin-top: var(--sp-5); }
.stat b { display: block; font-family: var(--font-serif); font-size: 2rem; font-weight: 600; color: var(--ink); }
.stat span { font-size: 13.5px; color: var(--ink-3); }
/* Home "track record" band: whole-career numbers, larger, bolder, centered, sitting just below the
   hero (distinct from the small inline .stats used inside content sections). Add to styleguide when locked. */
.stats.stats-lead { justify-content: center; text-align: center; gap: clamp(28px, 5vw, 64px); margin-top: var(--sp-6, 40px); }
.stats.stats-lead .stat b { font-size: clamp(2.1rem, 3.6vw, 2.9rem); line-height: 1; }
.stats.stats-lead .stat span { font-size: 15px; color: var(--ink-2); }

.quote { padding: 28px; }
.quote p { font-size: 16px; color: var(--ink); font-family: var(--font-serif); line-height: 1.5; margin-bottom: 20px; }
.quote .who { display: flex; align-items: center; gap: 12px; }
.quote .who .av { width: 40px; height: 40px; border-radius: 50%; background: var(--lime-wash); flex: none; }
.quote .who b { display: block; font-size: 14px; color: var(--ink); }
.quote .who span { display: block; font-size: 12.5px; color: var(--ink-3); }

.band { text-align: center; max-width: var(--measure); margin: 0 auto; }
.band .btn-row { justify-content: center; margin-top: 32px; }
/* a centered media block (screenshot) following a centered .band gets clear separation from it */
.band + .center-measure, .band + .shot { margin-top: var(--sp-5); }
/* a centered note/link placed after a stats row (e.g. "see selected work" under the track-record numbers) */
.stats + .center-measure { margin-top: var(--sp-5); }

/* ---------------- NorthStar page ---------------- */
/* inline email-capture waitlist form (hero + closing) */
.capture { display: flex; gap: 10px; max-width: 420px; }
/* the closing waitlist form sits in a centered .band, so it centers itself there */
.band .capture { margin-inline: auto; margin-top: var(--sp-4); }
.band .trust { margin-top: var(--sp-3); }
.capture input { flex: 1; min-width: 0; border: 1.5px solid var(--line-2); border-radius: var(--radius-sm);
  padding: 13px 16px; font-size: 16px; font-family: inherit; color: var(--ink); background: var(--surface); }
.capture input:focus { outline: none; border-color: var(--ink); }
.capture .btn { flex: none; }

/* 3-step "how it works" */
.steps { display: grid; grid-template-columns: repeat(3, minmax(0,1fr)); gap: var(--sp-4); }
/* a single row of 4 sequence cards (e.g. NorthStar Diary/Writer/Hunter/Tracker), responsive down */
.steps.steps-row { grid-template-columns: repeat(4, minmax(0,1fr)); gap: var(--sp-3); margin-top: 25px;}
@media (max-width: 1100px){ .steps.steps-row { grid-template-columns: repeat(2, minmax(0,1fr)); } }
@media (max-width: 560px){ .steps.steps-row { grid-template-columns: 1fr; } }
/* boxless steps: keep the numbered flow but drop the card box, for card-light pages */
.steps.steps-plain .step { border: 0; padding: 0; background: none; box-shadow: none; }
.steps.steps-plain .step:hover { border: 0; box-shadow: none; }
/* each step is a card with a solid-lime numbered badge on top — turns a plain 3-column text
   list into something with a clear visual anchor per step, so the section reads as a designed
   process instead of three paragraphs. */
.step { display: flex; flex-direction: column; padding: 30px 28px; border: 1px solid var(--line);
  border-radius: var(--radius-lg); background: var(--surface); transition: border-color .15s, box-shadow .15s; }
.step:hover { border-color: var(--line-2); box-shadow: var(--shadow-sm); }
.step .n { width: 52px; height: 52px; border-radius: 50%; background: var(--lime); color: var(--ink);
  display: grid; place-items: center; font-family: var(--font-serif); font-size: 1.4rem; font-weight: 700;
  margin-bottom: 20px; flex: none; }
/* h3 margin-bottom now comes from the base rule (8px) */
.step .sub { margin-bottom: 14px; }
.step ul { list-style: none; display: grid; gap: 10px; }
.step ul li { font-size: 14.5px; color: var(--ink-2); padding-left: 18px; position: relative; }
.step ul li::before { content: ""; position: absolute; left: 0; top: 9px; width: 6px; height: 6px; border-radius: 50%; background: var(--line-2); }

/* product screenshot gallery */
.gallery { display: grid; grid-template-columns: repeat(3, minmax(0,1fr)); gap: var(--sp-3); }
.gallery figure { border: 1px solid var(--line); border-radius: var(--radius-lg); overflow: hidden; background: var(--surface); }
.gallery .zoomshot { aspect-ratio: 16/10; }   /* the screenshot area — image sits natural-size, clipped, zoomable */
.gallery figcaption { padding: 16px 18px 20px; font-family: var(--font-serif); font-size: 1.05rem; font-weight: 600; color: var(--ink); }
.gallery figcaption span { display: block; font-family: var(--font-sans); font-size: 13px; font-weight: 500; color: var(--ink-3); margin-top: 4px; }

/* colstrip: a row of columns split by hairlines, no card boxes (e.g. NorthStar "AI helps, you decide") */
.colstrip { display: grid; grid-template-columns: repeat(4, minmax(0,1fr)); margin-top:25px;}
.colstrip > * { padding: 0 var(--sp-4); border-left: 1px solid var(--line); }
.colstrip > *:first-child { padding-left: 0; border-left: 0; }
.colstrip h3 { font-size: 1.05rem; margin-bottom: 8px; }
.colstrip p { font-size: 15px; color: var(--ink-2); }
@media (max-width: 1100px){ .colstrip { grid-template-columns: 1fr 1fr; row-gap: var(--sp-4); }
  .colstrip > * { padding: 0 var(--sp-4); } .colstrip > *:nth-child(odd) { padding-left: 0; border-left: 0; } }
@media (max-width: 560px){ .colstrip { grid-template-columns: 1fr; }
  .colstrip > * { padding: var(--sp-3) 0 0; border-left: 0; border-top: 1px solid var(--line); }
  .colstrip > *:first-child { padding-top: 0; border-top: 0; } }

/* NorthStar vs. generic-AI-tool comparison table */
/* the NorthStar column carries a continuous lime-wash tint from header to last row, so the
   "who wins" read is instant without needing to read every cell — the muted "them" column and
   neutral label column do the opposite work, receding instead of competing for attention */
.vs-wrap { border: 1px solid var(--line); border-radius: var(--radius-lg); overflow: hidden; overflow-x: auto; background: var(--surface); }
.vs { width: 100%; border-collapse: collapse; min-width: 560px; }
.vs th, .vs td { padding: 18px 22px; text-align: left; font-size: 14.5px; border-top: 1px solid var(--line); }
.vs thead th { background: var(--paper-2); font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: .02em; color: var(--ink-3); border-top: none; }
.vs thead th.us { background: var(--lime-wash); color: var(--lime-text); }
.vs-head { display: inline-flex; align-items: center; gap: 7px; }
.vs-head svg { width: 15px; height: 15px; }
.vs tbody td:first-child { color: var(--ink-3); font-weight: 600; }
.vs-val { display: inline-flex; align-items: center; gap: 9px; }
.vs-val svg { width: 16px; height: 16px; flex: none; }
.vs td.us { background: var(--lime-wash); color: var(--ink); font-weight: 600; }
.vs td.us .vs-val svg { color: var(--lime-text); }
.vs td.them { color: var(--ink-3); }
.vs td.them .vs-val svg { color: var(--ink-3); opacity: .55; }

.reframe { max-width: var(--measure); margin: 0 auto; text-align: center; }
.reframe h2 { margin-bottom: 16px; } /* same "heading immediately followed by a lead paragraph" pattern as .section-head h2 */


/* ---------------- vertical stack (the vertical counterpart to .grid.cols-N) ----------------
   .grid.cols-N lays things out in equal COLUMNS; .stack lays them in a single COLUMN with a
   consistent gap from the scale. Use it anywhere you were reaching for a wrapper div with an
   inline "display:grid;gap:..". Default gap --sp-3; .gap-sm / .gap-lg for the other steps. */
.stack { display: grid; gap: var(--sp-3); }
.stack.gap-sm { gap: var(--sp-2); }
.stack.gap-lg { gap: var(--sp-5); }

/* ---------------- numbered editorial list (home "what you'll learn") ----------------
   A reading-first alternative to a card grid: big serif numerals carry the rhythm, one item
   per row, scannable and calm. For a short set of subject areas you want people to actually read. */
.num-list { display: grid; gap: var(--sp-5); max-width: var(--w-narrow); }
.num-item { display: flex; gap: var(--sp-4); align-items: baseline; }
.num-item .n { font-family: var(--font-serif); font-size: 2.6rem; font-weight: 600; color: var(--line-2);
  flex: none; width: 68px; line-height: 1; }
.num-item h3 { margin-bottom: 6px; }
.num-item p { font-size: 15px; max-width: 56ch; }

/* ---------------- carousel (one .c-slide at a time + auto-built dots; see main.js) ---------------- */
.carousel { position: relative; }
.c-slide { display: none; }
.c-slide.active { display: block; }
.c-dots { display: flex; gap: 8px; justify-content: center; margin-top: var(--sp-4); }
.c-dots button { width: 8px; height: 8px; border-radius: 50%; border: none; padding: 0; background: var(--line-2);
  cursor: pointer; transition: background .15s, transform .15s; }
.c-dots button.active { background: var(--ink); transform: scale(1.15); }

/* single testimonial (inside a carousel) — centered, large serif quote */
.testimonial { max-width: var(--measure); margin: 0 auto; text-align: center; }
.testimonial .t-quote { font-family: var(--font-serif); font-size: clamp(1.15rem, 1.5vw, 1.35rem); font-weight: 400;
  line-height: 1.5; color: var(--ink); margin-bottom: var(--sp-3); }
.testimonial .t-who { font-size: 14px; color: var(--ink-3); }
.testimonial .t-who b { color: var(--ink); }
/* Testimonials carousel: stack every quote in one grid cell so the box is always as tall as the
   LONGEST quote and never resizes between slides. Scoped with :has(.testimonial) so the NorthStar
   hero-media carousel is untouched; degrades to the plain show/hide carousel on browsers without :has. */
.carousel:has(.testimonial) { display: grid; }
.carousel:has(.testimonial) .c-slide { grid-area: 1 / 1; display: block; visibility: hidden; }
.carousel:has(.testimonial) .c-slide.active { visibility: visible; }
.carousel:has(.testimonial) .c-dots { grid-area: 2 / 1; }

/* ---------------- zoomable screenshot + lightbox ----------------
   ONLY for product screenshots (the gallery, the home NorthStar shot). The image sits at its
   NATURAL size, top-left, clipped by a fixed-size container (never squashed to fit); hover shows
   a zoom badge; click opens the lightbox (see main.js) which defaults to fit-to-window with an
   "Actual size" toggle. Not for portraits / decorative images. */
.zoomshot { position: relative; overflow: hidden; cursor: zoom-in; background: var(--paper-2); }
.zoomshot img { display: block; max-width: none; } /* natural size — top-left corner shows */
.zoomshot::after { content: ""; position: absolute; inset: 0; background: rgba(26,26,26,0); transition: background .15s; pointer-events: none; }
.zoomshot:hover::after { background: rgba(26,26,26,.05); }
.zoom-badge { position: absolute; right: 12px; bottom: 12px; z-index: 2; display: inline-flex; align-items: center;
  gap: 6px; background: rgba(26,26,26,.82); color: #fff; font-size: 12px; font-weight: 600; padding: 6px 11px;
  border-radius: var(--radius-pill); opacity: 0; transition: opacity .15s; pointer-events: none; }
.zoomshot:hover .zoom-badge { opacity: 1; }
.zoom-badge svg { width: 14px; height: 14px; }

.lightbox { position: fixed; inset: 0; z-index: 400; background: rgba(18,18,18,.93); display: none; flex-direction: column; }
.lightbox.open { display: flex; }
.lb-bar { display: flex; justify-content: flex-end; gap: 10px; padding: 16px 20px; flex: none; }
.lb-bar .btn { background: rgba(255,255,255,.12); color: #fff; border-color: rgba(255,255,255,.28); }
.lb-bar .btn:hover { background: rgba(255,255,255,.22); }
.lb-stage { flex: 1; min-height: 0; overflow: auto; display: grid; place-items: center; padding: 0 20px 24px; }
.lb-stage img { max-width: 100%; max-height: 100%; object-fit: contain; border-radius: var(--radius); }
.lightbox.actual .lb-stage { place-items: start; }
.lightbox.actual .lb-stage img { max-width: none; max-height: none; border-radius: 0; }

/* ---------------- modern comparison (replaces the vs-table) ----------------
   Two contrasting columns as cards: NorthStar (lime, elevated) vs the generic tool (muted),
   each a plain checklist of full statements. Reads faster than a grid of terse table cells. */
.compare { display: grid; grid-template-columns: repeat(2, minmax(0,1fr)); gap: var(--sp-3); align-items: start; }
.compare-col { border: 1px solid var(--line); border-radius: var(--radius-lg); padding: 32px 28px; background: var(--surface); }
.compare-col.us { border-color: var(--ink); background: var(--lime-wash); box-shadow: var(--shadow-sm); }
.compare-col .ch { display: flex; align-items: center; gap: 10px; margin-bottom: var(--sp-3); }
.compare-col .ch h3 { margin: 0; }
.compare-col .ch .tag { margin-left: auto; }
.compare-col ul { list-style: none; display: grid; gap: 14px; }
.compare-col li { display: flex; align-items: flex-start; gap: 12px; font-size: 15px; color: var(--ink-2); }
.compare-col li svg { width: 18px; height: 18px; flex: none; margin-top: 1px; }
.compare-col.us li svg { color: var(--lime-text); }
.compare-col.them { color: var(--ink-3); }
.compare-col.them li { color: var(--ink-3); }
.compare-col.them li svg { color: var(--ink-3); opacity: .55; }
/* cmp: a modern row-by-row comparison table (dimension | us | them), scannable across the row.
   Replaces two separate lists so the reader compares line for line. */
.cmp { display: grid; grid-template-columns: 1fr 1.4fr 1.2fr; border: 1px solid var(--line); border-radius: var(--radius-lg); overflow: hidden; background: var(--surface); margin:25px auto 0px; max-width:1100px;}
.cmp > div { padding: 15px 20px; border-top: 1px solid var(--line); display: flex; align-items: center; gap: 10px; font-size: 15px; color: var(--ink-2); }
.cmp > div.cmp-row1 { border-top: 0; }
.cmp .cmp-h { font-family: var(--font-serif); font-weight: 600; color: var(--ink); font-size: 1.05rem; }
.cmp .cmp-dim { font-weight: 600; color: var(--ink); }
.cmp .cmp-us { background: var(--lime-wash); }
.cmp .cmp-us svg { color: var(--lime-text); }
.cmp .cmp-them { color: var(--ink-3); }
.cmp .cmp-them svg { color: var(--ink-3); opacity: .6; }
.cmp svg { width: 17px; height: 17px; flex: none; }
@media (max-width: 700px){ .cmp { grid-template-columns: 1fr; } .cmp > div { border-top: 1px solid var(--line); }
  .cmp .cmp-dim { background: var(--paper-2); font-family: var(--font-serif); } .cmp > div.cmp-row1 { display: none; } }

/* ---------------- resources page (downloads: decks, playbooks, templates, prompts) ----------------
   Free items email-gate then download; paid items sign in -> checkout -> file behind the wall. */
.res-controls { display: flex; gap: 12px; flex-wrap: wrap; align-items: center; margin-bottom: var(--sp-4); }
.res-search { flex: 1; min-width: 220px; position: relative; }
.res-search input { width: 100%; padding: 12px 16px 12px 42px; border: 1.5px solid var(--line-2);
  border-radius: var(--radius-sm); font-size: 15px; font-family: inherit; background: var(--surface); color: var(--ink); }
.res-search input:focus { outline: none; border-color: var(--ink); }
.res-search > svg { position: absolute; left: 14px; top: 50%; transform: translateY(-50%); width: 18px; height: 18px; color: var(--ink-3); }
.res-controls select { appearance: none; border: 1.5px solid var(--line-2); border-radius: var(--radius-sm);
  padding: 11px 38px 11px 14px; font-size: 14.5px; font-family: inherit; color: var(--ink); cursor: pointer;
  background: var(--surface) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%234a4a48' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E") no-repeat right 12px center; background-size: 15px; }
.res-controls select:focus { outline: none; border-color: var(--ink); }
.res-count { font-size: 14.5px; color: var(--ink-2); font-weight: 600; line-height: 1.5; margin-bottom: var(--sp-3); }
.res-count b { color: var(--ink); }

/* the whole card is a link to the detail page — so the grid isn't a wall of buttons; the "View"
   is a quiet text cue, not a third button style. */
.res-ph { position: absolute; inset: 0; display: grid; place-items: center; color: var(--line-2); }
.res-ph svg { width: 46px; height: 46px; }
.res-hidden { display: none !important; }

/* (public catalog pagination now uses the unified .pager above — the old .pagination was removed) */

/* ---------------- course detail ---------------- */
.cd-main { display: grid; gap: var(--sp-6); min-width: 0; }
.cd-main > section { min-width: 0; }

/* ---- content-page typography (course-detail, resource-detail) ----
   These are DENSE CONTENT pages, not marketing heroes. The global h1 (4.2rem) / h2 (2.9rem) are
   hero-scale and made these pages shout and feel cluttered with no hierarchy. Scope them down to a
   real content scale: title > section heading > lead > body. And give body copy a proper home
   (.prose) so paragraphs stop being set at .lead (hero-subtitle) size. */
.cd-main h1, .rd-main h1 { font-size: clamp(2.1rem, 3.4vw, 2.8rem); }
.cd-main h2, .rd-main h2 { font-size: clamp(1.45rem, 2.2vw, 1.7rem); line-height: 1.15; margin-bottom: 12px; }
.cd-main h3, .rd-main h3 { font-size: 1.2rem; }
/* section body copy: 18px, comfortable measure. Sits clearly below .lead (23px). */
.prose { font-size: 18px; line-height: 1.7; color: var(--ink-2); max-width: 66ch; }
.prose + .prose { margin-top: 14px; }
.prose-muted { color: var(--ink-3); }
.prose-label { display: block; font-size: 12.5px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .05em; color: var(--ink-3); margin-bottom: 4px; }
.cd-inst { display: grid; grid-template-columns: 160px minmax(0,1fr); gap: var(--sp-4); align-items: start; }
.cd-inst .frame { aspect-ratio: 1/1; }
.cd-inst-role { color: var(--lime-text); font-weight: 600; margin: 2px 0 10px; }

/* ---------------- resource detail (product-style, not a blog) ---------------- */
/* same two-column .with-rail layout as the event page; section rhythm matched to it (--sp-7) */
.rd-main { display: grid; gap: var(--sp-7); min-width: 0; }
.rd-main > section { min-width: 0; }

/* ---- Detail-page hero (course / resource / event), reworked layout ----
   Breadcrumb pinned to the top with generous space under it; the rest of the intro (chips, title, lead,
   fact capsules) grouped with an even gap and vertically centred against the taller side card. */
.detail-hero { display: flex; flex-direction: column; min-width: 0; }
.detail-hero .crumbs { margin-bottom: 62px; }
.detail-hero-body { margin-block: auto; display: flex; flex-direction: column; gap: 42px; align-items: flex-start; }
.detail-hero-body > * { margin: 0; }
.detail-hero h1 { font-size: clamp(2rem, 3.2vw, 2.7rem); }
/* fact "capsules": key facts (duration, lessons, level, seats) as filled pills so they catch the eye on a
   plain background instead of reading as quiet inline text. Add .caps to a .meta-row. */
.meta-row.caps { gap: 10px; }
.meta-row.caps .meta-item { background: var(--paper-2); border: 1px solid var(--line); padding: 8px 14px 8px 12px; border-radius: var(--radius-pill); }
.meta-row.caps .meta-item b { color: var(--ink); }
/* curriculum: readable size, a solid card surface so it never merges with a tinted section, clearer hover */
.curric details { background: var(--surface); }
.curric details:hover { border-color: var(--line-2); box-shadow: 0 6px 20px rgba(13,15,20,.05); }
.curric .ctitle { font-size: 17px; }
.curric .lesson { font-size: 15.5px; }

/* the cover sits at the top of the buy box like a product thumbnail */
.enroll { overflow: hidden; }
.enroll .rd-cover { border: none; margin: -30px -30px 22px; border-radius: var(--radius-lg) var(--radius-lg) 0 0; }
.enroll .guarantee { display: flex; align-items: flex-start; gap: 8px; font-size: 13px; color: var(--ink-3); margin-top: 14px; line-height: 1.5; }
.enroll .guarantee svg { width: 15px; height: 15px; flex: none; margin-top: 1px; color: var(--lime-text); }

/* icon cards — a meaningful icon + title + one line, used for what's-inside and who-it's-for */
.icards { display: grid; gap: 30px 80px; justify-content: center; }
.icards.cols-2 { grid-template-columns: max-content max-content; }
.icard { display: flex; gap: 14px; align-items: flex-start; }
/* max-content columns don't shrink, so stack to one column before they overflow small screens */
@media (max-width: 860px){ .icards.cols-2 { grid-template-columns: 1fr; } }
.icard .ic-chip { flex: none; }
.icard b { display: block; font-size: 15px; color: var(--ink); margin-bottom: 3px; }
.icard p { font-size: 14px; color: var(--ink-2); margin: 0; line-height: 1.5; }

/* locked peek — a real sample that fades out under a lock + buy */
.peeks { display: grid; gap: 18px; }
.peek { border: 1px solid var(--line); border-radius: var(--radius-lg); padding: 22px 24px; background: var(--surface); }
.peek h3 { font-size: 1.05rem; margin-bottom: 12px; }
/* a reading "excerpt" of the resource — serif for an editorial sample feel (NOT monospace, per house rule) */
.peek-body { font-family: var(--font-serif); font-size: 16px; line-height: 1.7;
  color: var(--ink-2); position: relative; }
.peek.locked .peek-body { max-height: 84px; overflow: hidden; }
.peek.locked .peek-body::after { content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 58px;
  background: linear-gradient(rgba(255,255,255,0), var(--surface)); }
.peek-lock { display: flex; align-items: center; gap: 10px; margin-top: 16px; font-size: 14px; font-weight: 600; color: var(--ink-3); }
.peek-lock .pl-ic { display: inline-flex; color: var(--lime-text); }
.peek-lock .pl-ic svg { width: 18px; height: 18px; }
.peek-lock .btn { margin-left: auto; }

/* prerequisites — icon + label chips */
.prereqs { display: flex; gap: 10px; flex-wrap: wrap; }
.prereq { display: inline-flex; align-items: center; gap: 8px; border: 1px solid var(--line-2);
  border-radius: var(--radius-pill); padding: 8px 15px; font-size: 14px; font-weight: 600; color: var(--ink-2); }
.prereq svg { width: 17px; height: 17px; flex: none; color: var(--lime-text); }

/* ---------------- contact page ---------------- */
.contact-side { display: grid; gap: 18px; align-content: start; }
.contact-item { display: flex; gap: 14px; align-items: flex-start; }
.ci-ic { width: 42px; height: 42px; flex: none; border-radius: var(--radius); background: var(--lime-wash);
  color: var(--lime-text); display: grid; place-items: center; }
.ci-ic svg { width: 20px; height: 20px; }
.contact-item b { display: block; font-size: 14.5px; margin-bottom: 2px; }
.contact-item a, .contact-item .muted { font-size: 14px; line-height: 1.5; }
.notecard .btn { margin-top: var(--sp-3); }

/* ---------------- responsive ---------------- */
@media (max-width: 960px) {
  .hero-grid, .hero-grid.media-lg { grid-template-columns: 1fr; }
  .hero-photo { order: -1; aspect-ratio: 16/9; }
  .split { grid-template-columns: 1fr; }
  .steps, .gallery { grid-template-columns: 1fr; }
  .compare { grid-template-columns: 1fr; }
  .num-item .n { width: 52px; font-size: 2.1rem; }
  .capture { max-width: none; }
  .plans, .stat-row { grid-template-columns: 1fr 1fr; }
  .plans { align-items: stretch; }
  .plan.feature { min-height: 0; }
  .ccard.featured { grid-template-columns: 1fr; }
  .pl { grid-template-columns: 1fr; }
  .pl-side { position: static; }
  .card.horizontal { flex-direction: column; }
  .co { grid-template-columns: 1fr; gap: 36px; }
  .co-summary { position: static; }
  .enroll { position: static; }
  .cd-inst { grid-template-columns: 120px minmax(0,1fr); }
  .icards.cols-2 { grid-template-columns: 1fr; }
  .grid2 { grid-template-columns: 1fr; }
  .legal-wrap { grid-template-columns: 1fr; gap: 28px; }
  .legal-side { position: static; display: flex; flex-wrap: wrap; gap: 4px 18px; }
  .lic-grid { grid-template-columns: 1fr 1fr; }
  .admin-grid { grid-template-columns: 1fr; }
  .admin-stats { grid-template-columns: 1fr 1fr; }
  .inv-parties, .inv-top { grid-template-columns: 1fr; }
  .nav-main, .nav-auth { display: none; }
  .nav-main.open { display: flex; position: absolute; top: var(--nav-h); left: 0; right: 0; flex-direction: column;
    background: var(--paper); border-bottom: 1px solid var(--line); padding: 16px 5%; gap: 8px; margin-left: 0; }
  .nav-burger { display: block; }
  /* mobile-only account/auth links live inside the open burger menu (nav-auth is hidden on mobile) */
  .nav-main.open .nav-m-only { display: block; background: none; border: 0; text-align: left; font: inherit;
    font-size: 15.5px; font-weight: 600; color: var(--ink-2); cursor: pointer; padding: 4px 0; }
  .nav-main.open .nav-m-only:hover { color: var(--ink); }
  .nav-main.open .nav-m-sep { display: block; height: 1px; background: var(--line); margin: 6px 0; }
  /* Archive dropdown: on mobile the menu is a stacked list, so show "Selected Work" inline (no hover). */
  .nav-main.open .nav-drop-top { display: none; }
  .nav-main.open .nav-drop { display: block; position: static; border: 0; box-shadow: none; padding: 0; min-width: 0; }
  .nav-main.open .nav-drop a { padding: 4px 0; font-size: 15.5px; }
  .admin { grid-template-columns: 1fr; }
  .admin-side { position: static; height: auto; flex-direction: row; flex-wrap: wrap; }
  /* .sg-* responsive rules moved to styleguide.css */
  .ptable .ptable-row { grid-template-columns: 1fr !important; gap: 6px; }
  .ptable-head { display: none; }
}
@media (max-width: 560px) {
  .stat-row, .plans { grid-template-columns: 1fr; }
  .toast-stack { left: 12px; right: 12px; max-width: none; }
}

/* ---- Share cluster (detail pages; component: includes/share.php + [data-share] in main.js).
   Copy-link + LinkedIn / X / WhatsApp, plus a native-share button JS reveals on mobile. ---- */
.enroll-share { margin-top: var(--sp-25); padding-top: var(--sp-25); border-top: 1px solid var(--line); }
.share { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.share-label { font-size: var(--text-sm); color: var(--ink-3); font-weight: 600; margin-right: 2px; }
.share-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 38px; height: 38px; padding: 0; border-radius: var(--radius-sm);
  border: 1px solid var(--line-2); background: var(--surface); color: var(--ink-2);
  cursor: pointer; text-decoration: none; transition: border-color .15s, color .15s, background .15s;
}
.share-btn svg { width: 19px; height: 19px; display: block; }
.share-btn:hover { border-color: var(--ink); color: var(--ink); background: var(--paper-2); }
.share-btn:focus-visible { outline: 2px solid var(--lime); outline-offset: 2px; }

/* ---- Detail-page additions: struck compare-at price, the "what you get" extras list, video embed ---- */
.price-was { color: var(--ink-3); text-decoration: line-through; font-weight: 600; font-size: 0.7em; margin-right: 2px; }
.enroll-extras { list-style: none; margin: var(--sp-25) 0 0; padding: var(--sp-25) 0 0; border-top: 1px solid var(--line); display: flex; flex-direction: column; gap: 10px; }
.enroll-extras li { display: flex; align-items: flex-start; gap: 9px; font-size: var(--text-sm); color: var(--ink-2); line-height: 1.5; }
.enroll-extras li svg { width: 17px; height: 17px; flex: none; margin-top: 1px; color: var(--lime-text); }
.enroll-extras .enroll-terms { color: var(--ink-3); }
.enroll-extras a { color: var(--ink-2); text-decoration: underline; text-underline-offset: 2px; }
.video-embed { position: relative; width: 100%; aspect-ratio: 16 / 9; border-radius: var(--radius-lg); overflow: hidden; border: 1px solid var(--line); background: #000; }
.video-embed iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }

/* ---- Dashboard (app/dashboard.php) + My learning (app/my-learning.php): benefit-focused KPI row + each
   section a fixed-height card whose list scrolls inside, so the page itself stays short. (Approved in
   _preview-app.php.) Progress fills in from lesson_progress once the LMS player writes it. ---- */
.dash { display: flex; flex-direction: column; gap: 22px; }
.dash-kpis { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 16px; margin-bottom: 4px; }
.dash-kpis .statcard { cursor: default; }
.dash-kpis .statcard b { font-size: 1.9rem; font-weight: 800; line-height: 1; display: block; margin-bottom: 6px; letter-spacing: -0.02em; }
@media (max-width: 720px) { .dash-kpis { grid-template-columns: repeat(2, 1fr); } }
.dash-sec { border: 1px solid var(--line); border-radius: var(--radius-lg); background: var(--surface); display: flex; flex-direction: column; height: 340px; overflow: hidden; }
.dash-sec-h { flex: none; display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 16px 20px; border-bottom: 1px solid var(--line); }
.dash-sec-h h2 { font-size: 1.1rem; font-weight: 700; margin: 0; letter-spacing: -0.01em; }
.dash-sec-h .link { font-size: 13px; font-weight: 600; color: var(--lime-text); }
.dash-sec-body { flex: 1; overflow-y: auto; padding: 6px 20px 12px; }
.dash-item { display: flex; gap: 16px; align-items: center; padding: 16px 0; border-bottom: 1px solid var(--line); }
.dash-item:last-child { border-bottom: none; }
.dash-item .thumb { width: 104px; height: 62px; border-radius: 10px; flex: none; background: linear-gradient(135deg, #1b1e27, #33384a); display: grid; place-items: center; color: rgba(255,255,255,.7); overflow: hidden; }
.dash-item .thumb svg { width: 26px; height: 26px; }
.dash-item .thumb img { width: 100%; height: 100%; object-fit: cover; }
.dash-item .di-main { flex: 1; min-width: 0; }
.dash-item .di-title { font-size: 15px; font-weight: 600; color: var(--ink); }
.dash-item .prog { margin: 9px 0 7px; max-width: 340px; }
.dash-item .di-meta { display: flex; flex-wrap: wrap; gap: 6px 14px; font-size: 12.5px; color: var(--ink-3); }
.dash-item .di-meta b { color: var(--ink-2); font-weight: 600; }
.dash-item .di-act { flex: none; }
.dash-line { display: flex; gap: 14px; align-items: center; padding: 14px 0; border-bottom: 1px solid var(--line); }
.dash-line:last-child { border-bottom: none; }
.dash-line .dl-ic { width: 40px; height: 40px; border-radius: 10px; flex: none; display: grid; place-items: center; background: var(--lime-wash); color: var(--ink); }
.dash-line .dl-ic svg { width: 20px; height: 20px; }
.dash-line .dl-main { flex: 1; min-width: 0; }
.dash-line .dl-main b { font-size: 14.5px; font-weight: 600; display: block; }
.dash-line .dl-main span { font-size: 12.5px; color: var(--ink-3); }
.dash-empty { height: 100%; display: grid; place-content: center; justify-items: center; text-align: center; padding: 20px; }
.dash-empty .de-ic { width: 52px; height: 52px; border-radius: 50%; display: grid; place-items: center; background: var(--paper-2); color: var(--ink-3); margin-bottom: 14px; }
.dash-empty .de-ic svg { width: 26px; height: 26px; }
.dash-empty p { color: var(--ink-3); font-size: 14.5px; line-height: 1.6; margin: 0 0 18px; max-width: 42ch; }
.dash-wait { display: flex; gap: 14px; align-items: center; padding: 14px 0; border-bottom: 1px solid var(--line); }
.dash-wait:last-child { border-bottom: none; }
.dash-wait .dw-main { flex: 1; min-width: 0; }
.dash-wait .dw-main b { font-size: 14.5px; font-weight: 600; display: block; }
.dash-wait .dw-main span { font-size: 12.5px; color: var(--ink-3); }
.dash-wait .tag { flex: none; }
.ml-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(340px, 1fr)); gap: 22px; }
.ml-card { border: 1px solid var(--line); border-radius: var(--radius-lg); background: var(--surface); overflow: hidden; display: flex; flex-direction: column; }
.ml-cover { aspect-ratio: 16/7; background: linear-gradient(135deg, #1b1e27, #33384a); display: grid; place-items: center; color: rgba(255,255,255,.7); position: relative; }
.ml-cover svg { width: 34px; height: 34px; }
.ml-cover img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.ml-cover .ml-done { position: absolute; top: 12px; right: 12px; }
.ml-body { padding: 18px 20px 20px; display: flex; flex-direction: column; flex: 1; }
.ml-body h3 { font-size: 1.05rem; margin: 0 0 4px; }
.ml-body .ml-sub { font-size: 13px; color: var(--ink-3); margin: 0 0 16px; }
.ml-body .prog { margin-bottom: 8px; }
.ml-body .ml-meta { font-size: 12.5px; color: var(--ink-3); margin-bottom: 4px; }
.ml-body .ml-meta b { color: var(--ink-2); font-weight: 600; }
.ml-body .ml-cur { font-size: 12.5px; color: var(--ink-3); margin-bottom: 16px; }
.ml-body .btn { margin-top: auto; }
.ml-body .ml-cert { margin-top: 8px; }
.ml-empty { grid-column: 1 / -1; }

/* ---- Curriculum builder (admin Curriculum tab; from _preview-builder.php) + the tiny rich-text editor.
   Chapters -> lessons -> ordered content blocks (video / rich text) + downloadable materials. ---- */
.cbwrap { max-width: 920px; padding-bottom: 40px; }
.cb-help { color: var(--ink-2); font-size: 15px; line-height: 1.6; margin-bottom: 24px; }
.cb-chap { border: 1px solid var(--line-2); border-radius: var(--radius-lg); background: var(--surface); margin-bottom: 20px; overflow: hidden; }
/* Chapters are an accordion: one open at a time, so the builder shows one chapter's lessons instead of the
   whole tree. Click the head (not the title field or the mini buttons) to expand/collapse. */
.cb-chap-head { display: flex; align-items: center; gap: 12px; padding: 16px 18px; background: var(--paper-2); cursor: pointer; }
.cb-chap.open .cb-chap-head { border-bottom: 1px solid var(--line); }
.cb-chap-chev { flex: none; width: 16px; height: 16px; color: var(--ink-3); transition: transform .2s; }
.cb-chap.open .cb-chap-chev { transform: rotate(90deg); }
.cb-chap-head .cb-num { font-size: 12px; font-weight: 800; letter-spacing: .04em; text-transform: uppercase; color: var(--ink-3); white-space: nowrap; }
.cb-chap-head input { flex: 1; min-width: 0; border: 1px solid var(--line-2); border-radius: var(--radius-sm); padding: 10px 12px; font: inherit; font-weight: 700; background: var(--surface); cursor: text; }
.cb-chap-count { font-size: 12px; color: var(--ink-3); white-space: nowrap; }
.cb-chap-body { display: none; padding: 14px 18px 18px; }
.cb-chap.open .cb-chap-body { display: block; }
.cb-les { border: 1px solid var(--line); border-radius: var(--radius); margin-bottom: 12px; background: var(--surface); }
.cb-les-sum { display: flex; align-items: center; gap: 12px; padding: 13px 15px; cursor: pointer; }
.cb-les-sum:hover { background: var(--paper-2); }
.cb-les.open .cb-les-sum { border-bottom: 1px solid var(--line); }
.cb-les-chev { flex: none; width: 16px; height: 16px; color: var(--ink-3); transition: transform .2s; }
.cb-les.open .cb-les-chev { transform: rotate(90deg); }
.cb-les-title { flex: 1; min-width: 0; font-weight: 600; font-size: 14.5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cb-les-title .muted { font-weight: 400; }
.cb-les-icons { flex: none; display: inline-flex; align-items: center; gap: 9px; color: var(--ink-3); }
.cb-les-icons svg { width: 16px; height: 16px; }
.cb-les-icons .fc { display: inline-flex; align-items: center; gap: 3px; font-size: 12px; font-weight: 600; }
.cb-les-body { display: none; padding: 4px 16px 18px; }
.cb-les.open .cb-les-body { display: block; }
.cb-free { display: inline-flex; align-items: center; gap: 8px; font-size: 13px; font-weight: 600; color: var(--ink-2); background: var(--lime-wash); border: 1px solid var(--lime); border-radius: var(--radius-pill); padding: 4px 12px; }
.cb-sub-h { font-size: 12px; font-weight: 800; letter-spacing: .04em; text-transform: uppercase; color: var(--ink-3); margin: 20px 0 10px; }
.cb-blocks { display: grid; gap: 12px; }
.cb-block { border: 1px solid var(--line); border-radius: 12px; overflow: hidden; }
.cb-block-head { display: flex; align-items: center; gap: 10px; padding: 8px 12px; background: var(--paper-2); border-bottom: 1px solid var(--line); font-size: 12.5px; font-weight: 700; color: var(--ink-2); }
.cb-block-head .cb-block-type { flex: 1; display: inline-flex; align-items: center; gap: 7px; }
.cb-block-head svg { width: 15px; height: 15px; }
.cb-mini { background: none; border: 1px solid var(--line-2); border-radius: 6px; width: 26px; height: 26px; display: grid; place-items: center; cursor: pointer; color: var(--ink-3); }
.cb-mini:hover { color: var(--ink); border-color: var(--ink-2); }
.cb-mini:disabled { opacity: .35; cursor: default; }
.cb-mini svg { width: 14px; height: 14px; }
.cb-block-body { padding: 12px; display: grid; gap: 10px; }
.cb-block-body > .btn { justify-self: start; }
.cb-block-body input.cb-vid, .cb-block-body input.cb-cap, .cb-block-body input.cb-title-in { width: 100%; border: 1px solid var(--line-2); border-radius: var(--radius-sm); padding: 10px 12px; font: inherit; }
.cb-block-body input.cb-title-in { font-weight: 600; }
.cb-img-prev img { max-width: 260px; max-height: 170px; border-radius: var(--radius-sm); border: 1px solid var(--line); display: block; }
.cb-addblock { display: flex; gap: 10px; margin-top: 4px; flex-wrap: wrap; }
.cb-mat-item { margin-bottom: 10px; }
.cb-mat-note { width: 100%; margin-top: 6px; border: 1px solid var(--line-2); border-radius: var(--radius-sm); padding: 8px 12px; font: inherit; font-size: 14px; resize: vertical; }
.cb-mat { display: flex; align-items: center; gap: 10px; padding: 9px 12px; border: 1px solid var(--line); border-radius: 10px; margin-bottom: 8px; }
.cb-mat-item .cb-mat { margin-bottom: 0; }
.cb-mat svg { width: 17px; height: 17px; color: var(--ink-3); flex: none; }
.cb-mat input { flex: 1; border: none; font: inherit; background: none; }
.cb-mat input:focus { outline: none; }
.cb-mat .cb-mat-size { flex: none; font-size: 12px; color: var(--ink-3); }
.cb-mat .cb-mini { margin-left: 4px; }
.rte { border: 1px solid var(--line-2); border-radius: var(--radius-sm); overflow: hidden; background: var(--surface); }
.rte-bar { display: flex; flex-wrap: wrap; gap: 2px; padding: 6px; border-bottom: 1px solid var(--line); background: var(--paper-2); }
.rte-bar button { border: none; background: none; cursor: pointer; width: 32px; height: 30px; border-radius: 6px; color: var(--ink-2); display: grid; place-items: center; font-weight: 700; font-size: 14px; }
.rte-bar button:hover { background: var(--surface); color: var(--ink); }
.rte-bar svg { width: 16px; height: 16px; }
.rte-bar .sep { width: 1px; background: var(--line); margin: 4px 4px; }
.rte-area { min-height: 120px; padding: 12px 14px; font: inherit; font-size: 15.5px; line-height: 1.7; outline: none; }
.rte-area:focus { box-shadow: inset 0 0 0 2px var(--lime-wash); }
.rte-area p { margin: 0 0 10px; } .rte-area h3 { margin: 14px 0 8px; font-size: 1.15rem; }
.rte-area ul, .rte-area ol { margin: 0 0 10px 22px; }
.rte-area:empty::before { content: attr(data-ph); color: var(--ink-3); }

/* ---- Distraction-free learning player (app/course-learning.php; from _preview-learn.php). Own fixed shell,
   no site nav/footer: top bar (close + breadcrumb + count), left curriculum (own scroll), right content
   (own scroll). Server-rendered per lesson so locked content is never sent to the browser. ---- */
.lp { position: fixed; inset: 0; display: flex; flex-direction: column; background: var(--paper); z-index: 40; }
.lp-head { flex: none; display: flex; align-items: center; gap: 18px; padding: 0 22px; height: 64px; border-bottom: 1px solid var(--line); background: var(--surface); }
.lp-close { flex: none; display: inline-flex; align-items: center; gap: 8px; height: 40px; padding: 0 14px; border: 1px solid var(--line-2); border-radius: var(--radius-sm); background: var(--surface); color: var(--ink-2); cursor: pointer; font: inherit; font-size: 14px; font-weight: 600; text-decoration: none; }
.lp-close:hover { background: var(--paper-2); color: var(--ink); }
.lp-close svg { width: 18px; height: 18px; }
.lp-crumb { flex: 1; min-width: 0; display: flex; align-items: center; gap: 9px; font-size: 14px; color: var(--ink-3); overflow: hidden; }
.lp-crumb .sep { opacity: .5; }
.lp-crumb .c-course { font-weight: 700; color: var(--ink); white-space: nowrap; }
.lp-crumb .c-cur { color: var(--ink-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.lp-right { flex: none; display: flex; align-items: center; gap: 20px; }
.lp-count { font-size: 13.5px; color: var(--ink-2); font-weight: 600; white-space: nowrap; }
.lp-count b { color: var(--ink); }
.lp-body { flex: 1; display: grid; grid-template-columns: 372px minmax(0, 1fr); min-height: 0; }
.lp-side { border-right: 1px solid var(--line); overflow-y: auto; background: var(--surface); }
.lp-side-top { padding: 26px 24px 22px; border-bottom: 1px solid var(--line); }
.lp-side-top h2 { font-size: 1.12rem; line-height: 1.3; margin-bottom: 16px; }
.lp-side-top .prog { margin-bottom: 10px; }
.lp-overview-link { display: flex; align-items: center; gap: 12px; padding: 16px 24px; border-bottom: 1px solid var(--line); cursor: pointer; font-weight: 600; font-size: 14.5px; color: var(--ink-2); text-decoration: none; }
.lp-overview-link:hover { background: var(--paper-2); color: var(--ink); text-decoration: none; }
.lp-overview-link.on { background: var(--lime-wash); color: var(--ink); box-shadow: inset 3px 0 0 var(--lime); }
.lp-overview-link svg { width: 20px; height: 20px; flex: none; color: var(--ink-3); }
.lp-overview-link.on svg { color: var(--ink); }
.lp-chap { border-bottom: 1px solid var(--line); }
.lp-chap-h { display: flex; align-items: center; gap: 12px; width: 100%; background: none; border: none; cursor: pointer; font: inherit; text-align: left; padding: 18px 24px; color: var(--ink); }
.lp-chap-h:hover { background: var(--paper-2); }
.lp-chev { flex: none; width: 16px; height: 16px; color: var(--ink-3); transition: transform .2s; }
.lp-chap.open .lp-chev { transform: rotate(90deg); }
.lp-chap-t { flex: 1; min-width: 0; font-weight: 700; font-size: 14.5px; line-height: 1.35; }
.lp-chap-m { flex: none; font-size: 11.5px; color: var(--ink-3); font-weight: 700; letter-spacing: .02em; }
.lp-chap-list { display: none; padding: 4px 14px 14px; }
.lp-chap.open .lp-chap-list { display: block; }
.lp-les { display: flex; align-items: flex-start; gap: 13px; padding: 13px 12px; border-radius: var(--radius-sm); cursor: pointer; color: var(--ink-2); text-decoration: none; }
.lp-les:hover { background: var(--paper-2); color: var(--ink); text-decoration: none; }
/* "active" = the item open in the main pane right now (strong fill). "current" = your resume / next-up
   lesson when you are NOT viewing it (a subtle left bar only), so the two never look identical. */
.lp-les.active { background: var(--lime-wash); color: var(--ink); box-shadow: inset 3px 0 0 var(--lime); }
.lp-les.current { box-shadow: inset 3px 0 0 var(--lime); color: var(--ink); }
.lp-les.locked { color: var(--ink-3); }
.lp-les-ic { width: 30px; height: 30px; border-radius: 50%; flex: none; display: grid; place-items: center; border: 1.5px solid var(--line-2); margin-top: 1px; }
.lp-les-ic svg { width: 16px; height: 16px; }
.lp-les.done .lp-les-ic { background: var(--lime); border-color: var(--lime); color: var(--ink); }
.lp-les.current .lp-les-ic, .lp-les.active .lp-les-ic { border-color: var(--ink); color: var(--ink); }
.lp-les-body { flex: 1; min-width: 0; }
.lp-les-t { display: block; font-size: 14px; line-height: 1.4; }
.lp-les-meta { display: flex; align-items: center; gap: 12px; margin-top: 7px; color: var(--ink-3); font-size: 12px; }
.lp-les-types { display: inline-flex; align-items: center; gap: 9px; }
.lp-les-types svg { width: 16px; height: 16px; }
.lp-les-types .lp-filecount { display: inline-flex; align-items: center; gap: 3px; font-weight: 600; }
.lp-les-dur { font-weight: 600; }
.lp-badge-free { font-size: 10px; font-weight: 800; letter-spacing: .04em; text-transform: uppercase; color: var(--ink); background: var(--lime); border-radius: var(--radius-pill); padding: 2px 7px; margin-left: 7px; vertical-align: 1px; }
.lp-main { overflow-y: auto; }
.lp-main-in { max-width: 1100px; margin: 0 auto; padding: 48px clamp(24px, 6vw, 76px) 110px; }
.lp-eyebrow { font-size: 12px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-3); margin-bottom: 12px; }
.lp-main-in h1 { font-size: clamp(1.9rem, 3vw, 2.5rem); line-height: 1.15; margin-bottom: 18px; }
.lp-sub { color: var(--ink-2); font-size: 1.15rem; line-height: 1.65; margin: 0 0 4px; }
.lp-ov-stats { display: flex; flex-wrap: wrap; gap: 10px 22px; margin-top: 14px; }
.lp-ov-stats span { display: inline-flex; align-items: center; gap: 8px; color: var(--ink-2); font-size: 14.5px; font-weight: 600; }
.lp-ov-stats svg { width: 17px; height: 17px; color: var(--ink-3); }
.lp-section { margin-top: 44px; }
.lp-section-h { font-size: 1.15rem; font-weight: 700; margin: 0; }
.lp-learn { list-style: none; display: grid; gap: 13px; margin: 0; padding: 0; }
.lp-learn li { display: flex; gap: 13px; align-items: flex-start; font-size: 16px; line-height: 1.5; }
.lp-learn li svg { flex: none; width: 22px; height: 22px; color: var(--lime-text); margin-top: 1px; }
.lp-mats { display: grid; gap: 10px; }
.lp-mat { display: flex; align-items: center; gap: 13px; padding: 15px 18px; border: 1px solid var(--line); border-radius: 12px; font-size: 14.5px; font-weight: 600; color: var(--ink); text-decoration: none; background: var(--surface); }
.lp-mat:hover { border-color: var(--line-2); box-shadow: var(--shadow-sm); }
.lp-mat svg { width: 20px; height: 20px; color: var(--ink-3); flex: none; }
.lp-mat .lp-mat-label { flex: 1; }
.lp-mat .lp-mat-x { margin-left: auto; font-size: 12.5px; color: var(--ink-3); font-weight: 600; }
.lp-mat-item { display: grid; gap: 6px; }
.lp-mat-note { margin: 0 2px; font-size: 13.5px; color: var(--ink-3); line-height: 1.55; }

/* ---- rendered content blocks (ns_render_blocks): text / image / video with optional captions. Shared by
   the learning page (course overview + lesson bodies, inside .lp-blocks) and the admin read-only curriculum
   view (inside .cblk-list). ---- */
.cblk { margin: 0 0 50px; }
.cblk:last-child { margin-bottom: 0; }
.cblk-text { line-height: 1.8; color: var(--ink); }
.cblk-text > :first-child { margin-top: 0; }
.cblk-text p { margin: 0 0 16px; }
.cblk-text h2 { font-size: 1.5rem; margin: 30px 0 0; }
.cblk-text h3, .cblk-text h4 { font-size: 1.2rem; margin: 26px 0 0; }
.cblk-text ul, .cblk-text ol { margin: 0 0 16px 24px; }
.cblk-title { font-size: 1.2rem; font-weight: 700; color: var(--ink); margin: 0 0 12px; }
.cblk-text a { color: var(--lime-text); text-decoration: underline; }
.cblk-img { text-align: center; }
.cblk-img img { display: block; width: 100%; border-radius: var(--radius-lg); border: 1px solid var(--line); cursor: zoom-in; }
/* click-to-zoom overlay for content images (learning page + anywhere blocks render) */
.img-zoom-overlay { position: fixed; inset: 0; z-index: 4000; display: grid; place-items: center; padding: 24px; background: rgba(12,12,14,.9); cursor: zoom-out; opacity: 0; transition: opacity .15s ease; }
.img-zoom-overlay.in { opacity: 1; }
.img-zoom-overlay img { max-width: 96vw; max-height: 94vh; border-radius: 8px; box-shadow: 0 12px 44px rgba(0,0,0,.5); }
.cblk-img figcaption, .cblk-cap { margin: 8px 0 0; font-size: 13.5px; color: var(--ink-3); text-align: center; }
.lp-blocks { margin-top: 20px; }
.lp-blocks .cblk-text { font-size: 16.5px; }
.cblk-list .cblk-img img { max-width: 460px; margin: 0 auto; }
.cblk-list .cblk-text { font-size: 15px; }
.lp-foot { display: flex; justify-content: space-between; align-items: center; gap: 16px; margin-top: 52px; padding-top: 28px; border-top: 1px solid var(--line); flex-wrap: wrap; }
.lp-foot .lp-upnext { font-size: 13.5px; color: var(--ink-3); }
.lp-foot .lp-upnext b { color: var(--ink-2); font-weight: 600; }
.lp-done-tag { display: inline-flex; align-items: center; gap: 8px; color: var(--lime-text); font-weight: 700; font-size: 15px; }
.lp-done-tag svg { width: 20px; height: 20px; }
.lp-locked-state { text-align: center; padding: 60px 0; }
/* Completion countdown label inside the Mark-complete button, + end-of-course test question UI */
.lp-timer { font-variant-numeric: tabular-nums; }
.test-q { margin-top: 0; }
.test-prompt { font-size: 18px; font-weight: 600; color: var(--ink); margin: 0 0 14px; line-height: 1.5; }
.test-opts { display: flex; flex-direction: column; gap: 10px; }
.test-opt { display: flex; align-items: flex-start; gap: 11px; padding: 12px 15px; border: 1px solid var(--line); border-radius: 10px; cursor: pointer; }
.test-opt:hover { border-color: var(--ink-2); }
.test-opt input { margin-top: 3px; flex: none; width: 17px; height: 17px; }
.test-opt span { color: var(--ink-2); line-height: 1.5; }
.lp-locked-state .lp-lk { width: 64px; height: 64px; border-radius: 50%; background: var(--paper-2); color: var(--ink-3); display: grid; place-items: center; margin: 0 auto 20px; }
.lp-locked-state .lp-lk svg { width: 30px; height: 30px; }
.lp-enroll-note { display: flex; gap: 14px; align-items: flex-start; background: var(--lime-wash); border: 1px solid var(--lime); border-radius: var(--radius); padding: 18px 20px; margin-bottom: 36px; font-size: 15px; line-height: 1.55; }
.lp-enroll-note svg { flex: none; width: 22px; height: 22px; color: var(--ink); margin-top: 1px; }
.lp-complete { text-align: center; padding: 40px 0; }
.lp-complete .lp-check { width: 82px; height: 82px; border-radius: 50%; background: var(--lime); color: var(--ink); display: grid; place-items: center; margin: 0 auto 24px; }
.lp-complete .lp-check svg { width: 42px; height: 42px; }
.lp-complete h1 { margin-bottom: 12px; }
@media (max-width: 860px) {
  .lp-body { grid-template-columns: 1fr; grid-template-rows: auto 1fr; }
  .lp-side { border-right: none; border-bottom: 1px solid var(--line); max-height: 42vh; }
  .lp-main-in { padding: 32px 22px 90px; }
}

/* Common Styles for overrides */
.ma-0 {margin: var(--sp-0) !important}
.mt-0 {margin-top: var(--sp-0) !important}
.mr-0 {margin-right: var(--sp-0) !important}
.mb-0 {margin-bottom: var(--sp-0) !important}
.ml-0 {margin-left: var(--sp-0) !important}

.pa-0 {padding:var(--sp-0) !important}
.pt-0 {padding-top: var(--sp-0) !important}
.pr-0 {padding-right: var(--sp-0) !important}
.pb-0 {padding-bottom: var(--sp-0) !important}
.pl-0 {padding-left: var(--sp-0) !important}