/* ==========================================================================
   SMEMinds Playbook Master — design system
   --------------------------------------------------------------------------
   Brand: navy #041947 (from the logo mark) + orange #FE7807.

   Theme rule: the COMPLETE light palette is defined on bare :root. Dark only
   ever REDEFINES tokens, in two guarded blocks — the OS preference (guarded so
   an explicit light choice always wins) and the explicit attribute. No colour
   gets its only definition inside a media query, and `color-scheme` is bound to
   the resolved theme so form controls never paint white-on-white.
   ========================================================================== */

:root {
  /* ---- brand ---------------------------------------------------------- */
  --navy-900:#020e28; --navy-800:#041947; --navy-700:#082455; --navy-600:#0d3269;
  --navy-500:#14427f; --navy-400:#2b5c9e; --navy-300:#5c86bd; --navy-200:#a8c2dd;
  --navy-100:#dce7f3; --navy-050:#eef4fa;

  --orange-700:#a34700; --orange-600:#c85a02; --orange-500:#e66c04;
  --orange-400:#fe7807;
  /* The brand orange is a fill colour, not a text-background colour: white on
     --orange-400 measures 2.66:1. These two are the accessible pair the
     primary button is painted with - 4.67:1 and 5.86:1 with white - keeping
     the same top-to-bottom depth the gradient always had. The scale above is
     untouched, because --orange-400 also drives focus rings, the rail accent
     and badge fills, which pass on their own grounds. */
  --orange-btn:#c25200; --orange-btn-2:#aa4600;
  --orange-300:#ff9640; --orange-200:#ffc08c; --orange-100:#ffe6d0;
  --orange-050:#fff5ec;

  --brand:var(--orange-400);
  --brand-strong:var(--orange-500);
  /* brand orange as INK on a light ground fails contrast at 3.4:1 — use the
     darker step whenever the orange is text rather than a fill. */
  --brand-ink:var(--orange-700);
  --brand-contrast:#ffffff;
  /* tinted brand background — must have a dark counterpart or the
     cream stays behind orange text when the theme flips */
  --brand-wash:var(--orange-050);

  /* ---- semantic ------------------------------------------------------- */
  --ok-500:#0f9d58; --ok-ink:#0b6b3c; --ok-bg:#e7f6ee;
  --warn-500:#e8a400; --warn-ink:#8a6200; --warn-bg:#fdf4dd;
  --err-500:#dc2626; --err-ink:#a11414; --err-bg:#fdeaea;
  --info-500:#2563eb; --info-ink:#1a45a8; --info-bg:#e8effd;

  /* ---- surfaces ------------------------------------------------------- */
  --bg:#f6f8fb;
  --bg-alt:#eef2f7;
  --surface:#ffffff;
  --surface-2:#f8fafc;
  --surface-3:#eff3f8;
  --surface-inset:#f2f5f9;
  --overlay:rgba(2,14,40,.55);
  --scrim:rgba(2,14,40,.72);

  /* ---- ink ------------------------------------------------------------ */
  --ink:#0c1b33;
  --ink-2:#3c4d68;
  --ink-3:#5b6a80;
  --ink-inv:#ffffff;
  --link:var(--navy-500);

  /* ---- lines ---------------------------------------------------------- */
  --line:#dfe6ef;
  --line-2:#c9d4e2;
  --line-strong:#a9b8cc;
  --focus:#1d6fe0;

  /* ---- elevation ------------------------------------------------------ */
  --sh-1:0 1px 2px rgba(4,25,71,.06), 0 1px 3px rgba(4,25,71,.05);
  --sh-2:0 2px 6px rgba(4,25,71,.07), 0 6px 16px rgba(4,25,71,.06);
  --sh-3:0 8px 20px rgba(4,25,71,.09), 0 18px 44px rgba(4,25,71,.10);
  --sh-4:0 20px 50px rgba(4,25,71,.16), 0 40px 90px rgba(4,25,71,.14);
  --sh-brand:0 8px 26px rgba(194,82,0,.30);

  /* ---- geometry ------------------------------------------------------- */
  /* one radius scale across the estate: 8/18/24 is what the eight builds
     and playbook-ui.css use; 9px and 26px here were the outliers */
  --r-xs:6px; --r-sm:8px; --r-md:13px; --r-lg:18px; --r-xl:24px; --r-full:999px;

  /* 4px base scale */
  --s-1:4px; --s-2:8px; --s-3:12px; --s-4:16px; --s-5:20px; --s-6:24px;
  --s-7:32px; --s-8:40px; --s-9:56px; --s-10:72px; --s-11:96px; --s-12:128px;

  /* ---- type ----------------------------------------------------------- */
  --font: "Inter var", "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI",
          Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif;
  /* Outfit for display, matching what all eight Playbook builds use for
     their headings. Before this the platform declared Inter here and
     loaded nothing, so headings fell back to Segoe UI and the homepage
     and the Playbooks were set in different faces. */
  --font-display: 'Outfit', 'Inter', -apple-system, BlinkMacSystemFont,
                  'Segoe UI', Roboto, sans-serif;
  --font-mono: ui-monospace, "SF Mono", "Cascadia Mono", "JetBrains Mono",
               Consolas, monospace;

  /* fluid scale — clamps mean no breakpoint ever has to restate a size */
  --t-xs:  clamp(.70rem, .68rem + .10vw, .76rem);
  --t-sm:  clamp(.80rem, .77rem + .14vw, .875rem);
  --t-md:  clamp(.92rem, .89rem + .16vw, 1rem);
  --t-lg:  clamp(1.05rem, 1.00rem + .24vw, 1.18rem);
  --t-xl:  clamp(1.22rem, 1.13rem + .42vw, 1.5rem);
  --t-2xl: clamp(1.45rem, 1.28rem + .80vw, 2rem);
  --t-3xl: clamp(1.62rem, 1.42rem + 0.95vw, 2.25rem);
  --t-4xl: clamp(1.95rem, 1.62rem + 1.60vw, 3.05rem);
  --t-5xl: clamp(2.30rem, 1.80rem + 2.45vw, 3.85rem);

  --lh-tight:1.12; --lh-snug:1.28; --lh:1.6; --lh-loose:1.75;
  --tracking-display:-.025em;

  /* ---- layout --------------------------------------------------------- */
  --wrap:1240px;
  --wrap-narrow:760px;
  --wrap-wide:1480px;
  --header-h:66px;
  --gutter:clamp(16px, 4vw, 40px);

  /* ---- motion --------------------------------------------------------- */
  --ease:cubic-bezier(.22,.61,.36,1);
  --ease-out:cubic-bezier(.16,1,.3,1);
  --fast:120ms; --base:220ms; --slow:400ms;

  color-scheme: light;
}

/* dark: OS preference, but an explicit light choice must still win */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg:#050d1e;
    --bg-alt:#020913;
    --surface:#0a1730;
    --surface-2:#0e1e3d;
    --surface-3:#132549;
    --surface-inset:#081428;
    --overlay:rgba(1,6,18,.7);
    --scrim:rgba(1,6,18,.85);

    --ink:#e8eefa;
    --ink-2:#a8b8d2;
    --ink-3:#7d8fae;
    --ink-inv:#041947;
    --link:#7fb0f5;

    --line:#1b2d51;
    --line-2:#263c66;
    --line-strong:#375280;
    --focus:#63a4ff;

    --brand:var(--orange-400);
    --brand-strong:var(--orange-300);
    /* on a dark ground the orange is already legible — no darkening needed */
    --brand-ink:var(--orange-300);
    --brand-contrast:#0b1220;
    --brand-wash:rgba(254,120,7,.15);

    --ok-ink:#5fd39a;  --ok-bg:#07281a;
    --warn-ink:#f5c451; --warn-bg:#2c2107;
    --err-ink:#ff8f8f;  --err-bg:#2e1013;
    --info-ink:#8fb4ff; --info-bg:#0d1c3c;

    --sh-1:0 1px 2px rgba(0,0,0,.5);
    --sh-2:0 2px 8px rgba(0,0,0,.55);
    --sh-3:0 10px 26px rgba(0,0,0,.6);
    --sh-4:0 24px 60px rgba(0,0,0,.7);
    --sh-brand:0 8px 26px rgba(194,82,0,.28);

    color-scheme: dark;
  }
}

/* dark: explicit choice */
:root[data-theme="dark"] {
  --bg:#050d1e; --bg-alt:#020913; --surface:#0a1730; --surface-2:#0e1e3d;
  --surface-3:#132549; --surface-inset:#081428;
  --overlay:rgba(1,6,18,.7); --scrim:rgba(1,6,18,.85);
  --ink:#e8eefa; --ink-2:#a8b8d2; --ink-3:#7d8fae; --ink-inv:#041947;
  --link:#7fb0f5;
  --line:#1b2d51; --line-2:#263c66; --line-strong:#375280; --focus:#63a4ff;
  --brand:var(--orange-400); --brand-strong:var(--orange-300);
  --brand-ink:var(--orange-300); --brand-contrast:#0b1220;
  --brand-wash:rgba(254,120,7,.15);
  --ok-ink:#5fd39a; --ok-bg:#07281a;
  --warn-ink:#f5c451; --warn-bg:#2c2107;
  --err-ink:#ff8f8f; --err-bg:#2e1013;
  --info-ink:#8fb4ff; --info-bg:#0d1c3c;
  --sh-1:0 1px 2px rgba(0,0,0,.5);
  --sh-2:0 2px 8px rgba(0,0,0,.55);
  --sh-3:0 10px 26px rgba(0,0,0,.6);
  --sh-4:0 24px 60px rgba(0,0,0,.7);
  --sh-brand:0 8px 26px rgba(194,82,0,.28);
  color-scheme: dark;
}
:root[data-theme="light"] { color-scheme: light; }

/* ==========================================================================
   reset
   ========================================================================== */
*,*::before,*::after { box-sizing:border-box; }
* { margin:0; }
html { -webkit-text-size-adjust:100%; scroll-behavior:smooth; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior:auto; }
  *,*::before,*::after {
    animation-duration:.01ms !important; animation-iteration-count:1 !important;
    transition-duration:.01ms !important; scroll-behavior:auto !important;
  }
}
body {
  font-family:var(--font);
  font-size:var(--t-md);
  line-height:var(--lh);
  color:var(--ink);
  background:var(--bg);
  -webkit-font-smoothing:antialiased;
  -moz-osx-font-smoothing:grayscale;
  text-rendering:optimizeLegibility;
  min-height:100dvh;
  overflow-x:hidden;
}
img,svg,video,canvas { display:block; max-width:100%; height:auto; }
input,button,textarea,select { font:inherit; color:inherit; }
button { background:none; border:0; cursor:pointer; }
a { color:var(--link); text-decoration:none; }
a:hover { text-decoration:underline; }
ul,ol { padding:0; list-style:none; }
table { border-collapse:collapse; width:100%; }
hr { border:0; border-top:1px solid var(--line); margin:var(--s-6) 0; }
[hidden] { display:none !important; }

:where(a,button,input,select,textarea,summary,[tabindex]):focus-visible {
  outline:2px solid var(--focus);
  outline-offset:2px;
  border-radius:var(--r-xs);
}

::selection { background:var(--orange-200); color:var(--navy-800); }

.sr-only {
  position:absolute; width:1px; height:1px; padding:0; margin:-1px;
  overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; border:0;
}
.skip-link {
  position:absolute; left:-9999px; top:0; z-index:200;
  /* on brand orange this measured 2.66:1 — the one control that exists purely
     for accessibility was the least accessible thing on the page. Navy carries
     white at 17:1; the orange stays as the focus ring. */
  background:var(--navy-900); color:#fff; padding:12px 18px;
  border-radius:0 0 var(--r-md) 0; font-weight:700;
}
.skip-link:focus {
  left:0;
  outline:3px solid var(--brand);
  outline-offset:2px;
}

/* ==========================================================================
   typography
   ========================================================================== */
h1,h2,h3,h4,h5 {
  font-family:var(--font-display);
  line-height:var(--lh-tight);
  letter-spacing:var(--tracking-display);
  font-weight:800;
  color:var(--ink);
  text-wrap:balance;
}
h1 { font-size:var(--t-4xl); }
h2 { font-size:var(--t-3xl); }
h3 { font-size:var(--t-xl); letter-spacing:-.015em; }
h4 { font-size:var(--t-lg); letter-spacing:-.01em; font-weight:700; }
h5 { font-size:var(--t-md); font-weight:700; letter-spacing:0; }
p  { text-wrap:pretty; }

.display { font-size:var(--t-5xl); font-weight:900; letter-spacing:-.035em; }
.lead    { font-size:var(--t-lg); color:var(--ink-2); line-height:var(--lh); }
.muted   { color:var(--ink-3); }
.small   { font-size:var(--t-sm); }
.tiny    { font-size:var(--t-xs); }
.mono    { font-family:var(--font-mono); font-variant-numeric:tabular-nums; }
.num     { font-variant-numeric:tabular-nums; letter-spacing:-.01em; }

.eyebrow {
  display:inline-flex; align-items:center; gap:var(--s-2);
  font-size:var(--t-xs); font-weight:700; letter-spacing:.12em;
  text-transform:uppercase; color:var(--brand-ink);
}
.grad-text {
  background:linear-gradient(96deg, var(--orange-400), var(--orange-300) 55%, #ffb367);
  -webkit-background-clip:text; background-clip:text; color:transparent;
}

/* ==========================================================================
   layout
   ========================================================================== */
.wrap { width:100%; max-width:var(--wrap); margin-inline:auto; padding-inline:var(--gutter); }
.wrap-narrow { max-width:var(--wrap-narrow); }
.wrap-wide { max-width:var(--wrap-wide); }
/* 7vw put 104px above AND below every section — 208px of nothing at each
   boundary on a desktop. 5vw keeps the breathing room on a phone, where the
   padding separates stacked content, and stops it ballooning on a wide screen
   where the alternating backgrounds already do the separating. */
.section { padding-block:clamp(44px, 5vw, 76px); }
.section-tight { padding-block:clamp(28px, 3.4vw, 52px); }

.stack > * + * { margin-top:var(--s-4); }
.stack-lg > * + * { margin-top:var(--s-7); }
.row { display:flex; align-items:center; gap:var(--s-3); }
.row-between { display:flex; align-items:center; justify-content:space-between; gap:var(--s-4); }
.wrapflex { flex-wrap:wrap; }
.spacer { flex:1 1 auto; }

.grid { display:grid; gap:var(--s-5); }
.grid-2 { grid-template-columns:repeat(auto-fit, minmax(min(100%, 320px), 1fr)); }
.grid-3 { grid-template-columns:repeat(auto-fit, minmax(min(100%, 290px), 1fr)); }
.grid-4 { grid-template-columns:repeat(auto-fit, minmax(min(100%, 220px), 1fr)); }

.section-head { max-width:66ch; margin-bottom:var(--s-7); }
.section-head h2 + p { margin-top:var(--s-3); }

/* A left-aligned head capped at 66ch leaves the right half of the measure
   blank above a full-width grid, which is what reads as empty space. Above
   1024px the title and its lead sit side by side instead: the head fills the
   measure and loses a line of height. Centred heads keep one column. */
@media (min-width:1024px) {
  .section-head:not(.tc):has(> h2 + p) {
    max-width:none;
    display:grid;
    grid-template-columns:minmax(0, 1.15fr) minmax(0, .85fr);
    grid-template-rows:auto auto;
    column-gap:var(--s-9);
    row-gap:var(--s-3);
  }
  /* placed explicitly rather than spanned: the lead belongs beside the
     HEADING, sitting on its last line, not floating up beside the eyebrow */
  .section-head:not(.tc):has(> h2 + p) > .eyebrow { grid-area:1 / 1; }
  .section-head:not(.tc):has(> h2 + p) > h2 { grid-area:2 / 1; margin-top:0; }
  .section-head:not(.tc):has(> h2 + p) > p {
    grid-area:2 / 2;
    align-self:end;
    margin-top:0;
    padding-bottom:.4em;
    max-width:50ch;
  }
  /* a head with no eyebrow has only one row */
  .section-head:not(.tc):has(> h2 + p):not(:has(> .eyebrow)) > h2 { grid-area:1 / 1; }
  .section-head:not(.tc):has(> h2 + p):not(:has(> .eyebrow)) > p { grid-area:1 / 2; }
}

/* ==========================================================================
   buttons
   ========================================================================== */
.btn {
  --btn-bg:var(--surface); --btn-ink:var(--ink); --btn-line:var(--line-2);
  display:inline-flex; align-items:center; justify-content:center; gap:var(--s-2);
  padding:11px 20px; min-height:44px;
  border:1px solid var(--btn-line); border-radius:var(--r-full);
  background:var(--btn-bg); color:var(--btn-ink);
  font-size:var(--t-sm); font-weight:650; letter-spacing:.005em;
  cursor:pointer; white-space:nowrap; text-decoration:none;
  transition:transform var(--fast) var(--ease), box-shadow var(--base) var(--ease),
             background var(--fast) linear, border-color var(--fast) linear;
}
.btn:hover { text-decoration:none; transform:translateY(-1px); box-shadow:var(--sh-2); }
.btn:active { transform:translateY(0); }
.btn[disabled],.btn[aria-disabled="true"] {
  opacity:.5; pointer-events:none; transform:none;
}
/* White on the old gradient measured 2.66:1 at the top stop and 3.23:1 at the
   bottom - both under the 4.5 floor, and white text sits across the whole
   gradient, so both had to move. The hosted Playbook apps had already reached
   the same conclusion independently with --orange-ink-bg (#c2410c, 5.18:1);
   this is that decision for the platform shell. */
.btn-primary {
  --btn-bg:linear-gradient(180deg, var(--orange-btn), var(--orange-btn-2));
  --btn-ink:#fff; --btn-line:transparent;
  /* The `background` shorthand on .btn resolves a gradient to background-image
     plus a transparent background-color. Naming the solid colour here is a real
     fallback, and it is the only thing a DOM walker — a contrast audit, the next
     person reading this — can read the button's ground from. A longhand in a
     later rule of equal specificity beats the shorthand's implied value, so this
     does not disturb the solid-colour variants. */
  background-color:var(--orange-btn);
  box-shadow:var(--sh-brand);
}
.btn-primary:hover { box-shadow:0 10px 30px rgba(194,82,0,.40); }
.btn-navy { --btn-bg:var(--navy-800); --btn-ink:#fff; --btn-line:transparent; }
/* on a dark ground the navy button disappears into the surface — lift it */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .btn-navy {
    --btn-bg:var(--surface-3); --btn-ink:var(--ink); --btn-line:var(--line-2);
  }
}
:root[data-theme="dark"] .btn-navy {
  --btn-bg:var(--surface-3); --btn-ink:var(--ink); --btn-line:var(--line-2);
}
.btn-ghost { --btn-bg:transparent; --btn-line:var(--line-2); }
.btn-quiet { --btn-bg:transparent; --btn-line:transparent; --btn-ink:var(--ink-2); }
.btn-quiet:hover { --btn-bg:var(--surface-3); box-shadow:none; }
.btn-lg { padding:15px 30px; min-height:54px; font-size:var(--t-md); font-weight:700; }
.btn-sm { padding:7px 14px; min-height:36px; font-size:var(--t-xs); }
.btn-block { width:100%; }
.btn-icon { padding:0; width:44px; min-height:44px; border-radius:var(--r-full); }
.btn-sm.btn-icon { width:36px; }

/* ==========================================================================
   cards & surfaces
   ========================================================================== */
.card {
  background:var(--surface);
  border:1px solid var(--line);
  border-radius:var(--r-lg);
  box-shadow:var(--sh-1);
  overflow:hidden;
}
.card-pad { padding:var(--s-6); }
.card-hover { transition:transform var(--base) var(--ease), box-shadow var(--base) var(--ease),
                         border-color var(--base) linear; }
.card-hover:hover { transform:translateY(-4px); box-shadow:var(--sh-3); border-color:var(--line-2); }

.panel {
  background:var(--surface-2); border:1px solid var(--line);
  border-radius:var(--r-md); padding:var(--s-5);
}
.inset { background:var(--surface-inset); border-radius:var(--r-md); padding:var(--s-5); }

.glass {
  background:color-mix(in srgb, var(--surface) 76%, transparent);
  backdrop-filter:saturate(1.6) blur(14px);
  -webkit-backdrop-filter:saturate(1.6) blur(14px);
  border:1px solid color-mix(in srgb, var(--line) 70%, transparent);
}

/* ==========================================================================
   chips / badges / pills
   ========================================================================== */
.chip {
  display:inline-flex; align-items:center; gap:6px;
  padding:5px 11px; border-radius:var(--r-full);
  background:var(--surface-3); border:1px solid var(--line);
  font-size:var(--t-xs); font-weight:600; color:var(--ink-2);
  white-space:nowrap;
}
.chip-brand { background:var(--brand-wash); border-color:var(--orange-200); color:var(--brand-ink); }
.chip-ok    { background:var(--ok-bg); border-color:transparent; color:var(--ok-ink); }
.chip-warn  { background:var(--warn-bg); border-color:transparent; color:var(--warn-ink); }
.chip-err   { background:var(--err-bg); border-color:transparent; color:var(--err-ink); }
.chip-info  { background:var(--info-bg); border-color:transparent; color:var(--info-ink); }

.ribbon {
  position:absolute; top:14px; right:14px; z-index:2;
  padding:5px 12px; border-radius:var(--r-full);
  background:var(--navy-800); color:#fff;
  font-size:var(--t-xs); font-weight:800; letter-spacing:.06em; text-transform:uppercase;
}
/* Same white-on-orange gradient as the primary button, and .ribbon sets
   color:#fff above - so it carried the same 2.66:1. Small uppercase text,
   so the 4.5 floor applies in full. */
.ribbon-brand {
  background:linear-gradient(180deg,var(--orange-btn),var(--orange-btn-2));
  background-color:var(--orange-btn);   /* real fallback; see .btn-primary */
}

.dot { width:8px; height:8px; border-radius:50%; background:var(--ink-3); flex:none; }
.dot-ok { background:var(--ok-500); }
.dot-warn { background:var(--warn-500); }
.dot-err { background:var(--err-500); }

/* ==========================================================================
   forms
   ========================================================================== */
.field { display:block; }
.field + .field { margin-top:var(--s-4); }
.label {
  display:block; margin-bottom:6px;
  font-size:var(--t-sm); font-weight:650; color:var(--ink-2);
}
.input, .select, .textarea {
  width:100%; padding:12px 14px; min-height:46px;
  background:var(--surface);
  color:var(--ink);                 /* never inherit `fieldtext` */
  border:1px solid var(--line-2);
  border-radius:var(--r-sm);
  transition:border-color var(--fast) linear, box-shadow var(--fast) linear;
}
.textarea { min-height:120px; resize:vertical; line-height:var(--lh); }
.input::placeholder, .textarea::placeholder { color:var(--ink-3); opacity:1; }
.input:focus, .select:focus, .textarea:focus {
  outline:none; border-color:var(--focus);
  box-shadow:0 0 0 3px color-mix(in srgb, var(--focus) 22%, transparent);
}
.input[aria-invalid="true"] { border-color:var(--err-500); }
.select {
  appearance:none;
  background-image:linear-gradient(45deg,transparent 50%,currentColor 50%),
                   linear-gradient(135deg,currentColor 50%,transparent 50%);
  background-position:calc(100% - 19px) 21px, calc(100% - 14px) 21px;
  background-size:5px 5px, 5px 5px; background-repeat:no-repeat;
  padding-right:38px;
}
.hint { margin-top:5px; font-size:var(--t-xs); color:var(--ink-3); }
.error-text { margin-top:5px; font-size:var(--t-xs); color:var(--err-ink); font-weight:600; }

.check { display:flex; align-items:flex-start; gap:10px; cursor:pointer; }
.check input { width:18px; height:18px; margin-top:2px; accent-color:var(--brand); flex:none; }

.switch { position:relative; width:44px; height:26px; flex:none; }
.switch input { position:absolute; opacity:0; width:100%; height:100%; margin:0; cursor:pointer; }
.switch span {
  position:absolute; inset:0; border-radius:var(--r-full);
  background:var(--line-strong); transition:background var(--base) var(--ease);
  pointer-events:none;
}
.switch span::after {
  content:""; position:absolute; top:3px; left:3px; width:20px; height:20px;
  border-radius:50%; background:#fff; box-shadow:var(--sh-1);
  transition:transform var(--base) var(--ease);
}
.switch input:checked + span { background:var(--brand); }
.switch input:checked + span::after { transform:translateX(18px); }
.switch input:focus-visible + span { outline:2px solid var(--focus); outline-offset:2px; }

/* ==========================================================================
   progress
   ========================================================================== */
.bar { height:8px; border-radius:var(--r-full); background:var(--surface-3); overflow:hidden; }
.bar > i {
  display:block; height:100%; border-radius:inherit;
  background:linear-gradient(90deg,var(--orange-400),var(--orange-300));
  transition:width var(--slow) var(--ease-out);
}
.bar-thin { height:5px; }
.bar-ok > i { background:linear-gradient(90deg,var(--ok-500),#3dc98a); }

.ring { --pct:0; --sz:56px; width:var(--sz); height:var(--sz); flex:none; position:relative; }
.ring::before {
  content:""; position:absolute; inset:0; border-radius:50%;
  background:conic-gradient(var(--brand) calc(var(--pct)*1%), var(--surface-3) 0);
  -webkit-mask:radial-gradient(circle, transparent 58%, #000 59%);
          mask:radial-gradient(circle, transparent 58%, #000 59%);
}
.ring > b {
  position:absolute; inset:0; display:grid; place-items:center;
  font-size:var(--t-xs); font-weight:800; font-variant-numeric:tabular-nums;
}

/* ==========================================================================
   tables
   ========================================================================== */
.table-wrap { overflow-x:auto; -webkit-overflow-scrolling:touch; border-radius:var(--r-md); }
.table { width:100%; font-size:var(--t-sm); }
.table th, .table td {
  padding:11px 14px; text-align:left; border-bottom:1px solid var(--line);
  vertical-align:middle;
}
.table th {
  font-size:var(--t-xs); font-weight:700; letter-spacing:.05em;
  text-transform:uppercase; color:var(--ink-3);
  background:var(--surface-2); position:sticky; top:0; z-index:1;
  white-space:nowrap;
}
.table tbody tr:hover { background:var(--surface-2); }
.table td.num, .table th.num { text-align:right; font-variant-numeric:tabular-nums; }

/* ==========================================================================
   callouts (used by imported lesson HTML)
   ========================================================================== */
.callout {
  display:flex; gap:var(--s-3);
  padding:var(--s-4) var(--s-5);
  border-radius:var(--r-md);
  border:1px solid var(--line);
  border-left:4px solid var(--info-500);
  background:var(--info-bg); color:var(--ink);
  margin-block:var(--s-5);
}
.callout.warning { border-left-color:var(--warn-500); background:var(--warn-bg); }
.callout.success { border-left-color:var(--ok-500);   background:var(--ok-bg); }
.callout.danger  { border-left-color:var(--err-500);  background:var(--err-bg); }
.callout strong { color:inherit; }

/* ==========================================================================
   toast / modal
   ========================================================================== */
.toasts {
  position:fixed; z-index:120;
  bottom:calc(18px + env(safe-area-inset-bottom));
  right:18px; left:auto;
  display:flex; flex-direction:column; gap:10px;
  max-width:min(380px, calc(100vw - 36px));
  pointer-events:none;
}
.toast {
  display:flex; align-items:flex-start; gap:10px;
  padding:13px 16px; border-radius:var(--r-md);
  background:var(--navy-800); color:#fff; box-shadow:var(--sh-3);
  font-size:var(--t-sm); pointer-events:auto;
  animation:toast-in var(--base) var(--ease-out);
}
.toast.err { background:var(--err-500); }
.toast.ok  { background:var(--ok-500); }
@keyframes toast-in { from { opacity:0; transform:translateY(10px) scale(.98); } }

dialog.modal {
  /* The `* { margin:0 }` reset above beats the UA's `dialog:modal { margin:auto }`,
     which is the rule that centres an open dialog — without this every modal on
     the platform pins itself to the top-left corner of the viewport. */
  margin:auto;
  width:min(560px, calc(100vw - 32px));
  padding:0; border:0; border-radius:var(--r-lg);
  background:var(--surface); color:var(--ink);
  box-shadow:var(--sh-4);
}
dialog.modal::backdrop { background:var(--scrim); backdrop-filter:blur(3px); }
.modal-head {
  display:flex; align-items:center; justify-content:space-between; gap:var(--s-4);
  padding:var(--s-5) var(--s-6); border-bottom:1px solid var(--line);
}
.modal-body { padding:var(--s-6); max-height:min(64vh, 560px); overflow:auto; }
.modal-foot {
  display:flex; gap:var(--s-3); justify-content:flex-end;
  padding:var(--s-4) var(--s-6); border-top:1px solid var(--line);
  background:var(--surface-2);
}

/* ==========================================================================
   skeleton / empty
   ========================================================================== */
.skel {
  background:linear-gradient(90deg,var(--surface-3) 25%,var(--surface-2) 50%,var(--surface-3) 75%);
  background-size:200% 100%; animation:shimmer 1.3s linear infinite;
  border-radius:var(--r-sm);
}
@keyframes shimmer { to { background-position:-200% 0; } }
.empty { text-align:center; padding:var(--s-9) var(--s-5); color:var(--ink-3); }
.empty .emoji { font-size:2.6rem; margin-bottom:var(--s-3); }

/* ==========================================================================
   utilities
   ========================================================================== */
.tc { text-align:center; } .tr { text-align:right; }
.mt-0{margin-top:0}.mt-2{margin-top:var(--s-2)}.mt-3{margin-top:var(--s-3)}
.mt-4{margin-top:var(--s-4)}.mt-5{margin-top:var(--s-5)}.mt-6{margin-top:var(--s-6)}
.mt-7{margin-top:var(--s-7)}.mt-8{margin-top:var(--s-8)}
/* The scale used to stop at 8 while the tokens ran to 12, so `mt-9` — used in
   eleven places, mostly to separate the Master Pass block from the grid above
   it — matched no rule and silently applied no margin at all. A utility class
   that does nothing fails quietly, so the whole token scale is covered here. */
.mt-9{margin-top:var(--s-9)}.mt-10{margin-top:var(--s-10)}
.mt-11{margin-top:var(--s-11)}.mt-12{margin-top:var(--s-12)}
.mb-0{margin-bottom:0}.mb-2{margin-bottom:var(--s-2)}.mb-3{margin-bottom:var(--s-3)}
.mb-4{margin-bottom:var(--s-4)}.mb-5{margin-bottom:var(--s-5)}.mb-6{margin-bottom:var(--s-6)}
.mb-7{margin-bottom:var(--s-7)}.mb-8{margin-bottom:var(--s-8)}
.mb-9{margin-bottom:var(--s-9)}
.hide { display:none !important; }
@media (max-width: 860px)  { .hide-md { display:none !important; } }
@media (max-width: 640px)  { .hide-sm { display:none !important; } }
@media (min-width: 861px)  { .only-md { display:none !important; } }
.nowrap { white-space:nowrap; }
.trunc { overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.clamp-2 { display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden; }
.clamp-3 { display:-webkit-box; -webkit-line-clamp:3; -webkit-box-orient:vertical; overflow:hidden; }
.full { width:100%; }


/* ------------------------------------------------- the Playbook detail page
   Scoped to `.pb-detail` so this tightens the Playbook pages and not the rest
   of the site. All nine come from one template, so all nine get it.

   The measured waste was vertical padding repeated six times over and a
   sidebar column left empty beside the curriculum; the curriculum now runs
   full width and these bring the rhythm in to match. */
.pb-detail .section { padding-block: clamp(34px, 3.4vw, 52px); }
.pb-detail .section-tight { padding-block: clamp(24px, 2.4vw, 36px); }
.pb-detail .section-head { margin-bottom: var(--s-5); }

/* The split is short now, so the sidebar sits beside it rather than stranding
   a column. Stretching the aside also gives its sticky card room to work. */
.pb-detail .split-2-1 { align-items: stretch; }
.pb-detail .split-2-1 > aside { height: 100%; }

/* The curriculum, at the width it always needed */
.pb-detail .pbx-inline { width: 100%; }

/* The hero ratio lives here, not inline. `.hero-grid` collapses to one column
   at 980px, and an inline grid-template-columns beat that media query — so the
   hero stayed two columns on a phone. Setting it inside a min-width query
   leaves the collapse intact. */
@media (min-width: 981px) {
  .pb-detail .hero-grid {
    grid-template-columns: minmax(0, 1fr) minmax(0, .86fr);
    gap: 44px;
  }
}

@media (max-width: 900px) {
  .pb-detail .section { padding-block: clamp(26px, 6vw, 36px); }
}
