/* Profesor Particular .IO — design system v7, "study desk"
 *
 * The look comes from what studying looks like: black ink on white, a
 * highlighter pass over the words that matter, a pen for marks, index
 * cards with tabs, and one seal shape (the logo rosette). Drawn with a fine
 * pen: 1px rules, medium weights, no heavy shadows.
 *
 * How it stays safe (the reason v7 exists, 15 Oct 2026):
 *   1. OPT-IN. Everything is scoped to `.ds`. A page uses the system by
 *      putting class="ds" on <body> and loading this file. Pages that have not
 *      migrated are never touched; no shared rule can leak into them.
 *   2. LAYERS. All rules live in @layer ds.*. A page's own (unlayered) CSS
 *      always beats the system, so a migrating page never fights specificity.
 *      Order inside: tokens < base < grounds < layout < components < legacy <
 *      templates *      < utilities. Templates style the class vocabulary of a page family
 *      (hubs today) so its hand-written HTML and generators keep working.
 *   3. GROUNDS. Every surface declares data-ground (paper, desk, ink, sky, hl).
 *      A ground sets the colour roles (--fg, --fg-2, --line, --pen-c, --btn...).
 *      Components only ever read roles, never raw colours, so any component
 *      on any ground is readable. That is the fallback.
 *   4. QA. templates/design-system.html shows every component on every
 *      ground; tools/audit-rendered-contrast.js renders it and fails on any
 *      text below WCAG AA.
 *
 * Mobile first: base rules are the phone; min-width queries add up.
 */

@layer ds.tokens, ds.base, ds.grounds, ds.layout, ds.components, ds.legacy, ds.templates, ds.utilities;

/* ── Tokens ─────────────────────────────────────────────────────────── */
@layer ds.tokens {
  .ds {
    /* Raw palette: only grounds read these */
    /* Ink is navy, like a blue ink pen (Vicente, 15 Oct 2026: "the blue
       navy, solid and beautiful"); neutrals are cool slate to match */
    --ink: #0f172a;
    --ink-2: #475569;
    --paper: #ffffff;
    --desk: #f1f5f9;
    --rule: #e2e8f0;
    --rule-2: #cbd5e1;
    --sky: #bfdbfe;
    --sky-ink: #0b1f5c;
    --sky-ink-2: #1e40af;
    --hl: #ffe14d;
    --hl-deep: #f5cf00;
    /* The pen is ink: no red anywhere (Vicente, 15 Oct 2026) */
    --pen: #0f172a;
    --pen-on-ink: #f8fafc;

    /* Type: one family, medium weights */
    /* Schibsted Grotesk for everything: a refined newspaper sans. Chosen by
       Vicente on 15 Oct 2026 from nine faces (Literata, Newsreader, Instrument
       Serif, Gloock, Besley, Bodoni Moda, Young Serif, Hedvig, Schibsted). */
    --font: "Schibsted Grotesk", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
    --font-display: var(--font);
    --w-head: 600;
    --w-strong: 600;
    --t-display: clamp(2.375rem, 5.2vw + 1rem, 4.5rem);
    --t-h2: clamp(1.75rem, 2.6vw + 1rem, 2.75rem);
    --t-h3: clamp(1.125rem, .5vw + 1rem, 1.3125rem);
    --t-lead: clamp(1.0625rem, .45vw + .95rem, 1.25rem);
    --t-body: 1rem;
    --t-small: .875rem;
    --t-label: .6875rem;

    /* Space: 4px steps */
    --s-1: 4px; --s-2: 8px; --s-3: 12px; --s-4: 16px; --s-5: 24px;
    --s-6: 32px; --s-7: 48px; --s-8: 64px; --s-9: 96px;
    --gutter: 20px;
    --max: 1160px;

    /* Shape: fine lines, small radius */
    --r: 6px;
    --r-lg: 10px;
    --hair: 1px;
    --ease: cubic-bezier(.2, 0, .2, 1);
    /* The highlighter strokes: a pass over the lower part of a word on light
       grounds, a full-height pass on ink (letters must not sit on the dark) */
    --hl-stroke: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 40' preserveAspectRatio='none'%3E%3Cpath d='M3 9C40 5 98 7 150 5c19-1 34 0 46 2l-2 25c-30 3-80 2-130 4-24 1-45 1-61-1z' fill='%23FFE14D' fill-opacity='.9'/%3E%3C/svg%3E");
    --hl-stroke-full: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 40' preserveAspectRatio='none'%3E%3Cpath d='M2 2C50 0 120 1 170 0c12 0 22 1 28 2l1 36c-48 2-118 2-176 1-8 0-15-1-21-2z' fill='%23FFE14D'/%3E%3C/svg%3E");
    --soft: 0 1px 2px rgba(15, 23, 42, .05), 0 8px 24px -12px rgba(15, 23, 42, .18);

    /* Stacking: same names and values as site-chrome.css */
    --ds-layer-nav: 100; --ds-layer-overlay: 6000; --ds-layer-modal: 8000; --ds-layer-popover: 9000; --ds-layer-toast: 10000;
  }
  @media (min-width: 768px) { .ds { --gutter: 40px; } }
}

/* ── Base ───────────────────────────────────────────────────────────── */
@layer ds.base {
  .ds, .ds *, .ds *::before, .ds *::after { box-sizing: border-box; }
  .ds {
    margin: 0;
    font-family: var(--font);
    font-size: var(--t-body);
    line-height: 1.6;
    font-optical-sizing: auto;
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
  }
  .ds :where(h1, h2, h3, h4, p, ul, ol, dl, dd, figure, blockquote) { margin: 0; }
  .ds :where(h1, h2, h3, h4) { font-family: var(--font-display); color: var(--fg); font-weight: var(--w-head); letter-spacing: -.022em; line-height: 1.08; text-wrap: balance; }
  .ds :where(h1) { font-size: var(--t-display); letter-spacing: -.032em; line-height: 1; }
  .ds :where(h2) { font-size: var(--t-h2); }
  .ds :where(h3) { font-size: var(--t-h3); letter-spacing: -.012em; line-height: 1.25; }
  .ds :where(p, li, dd) { text-wrap: pretty; }
  .ds :where(ul, ol) { padding: 0; list-style: none; }
  .ds :where(img, svg) { display: block; max-width: 100%; }
  .ds :where(a) { color: var(--link); text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: .2em; text-decoration-color: var(--link-line); }
  .ds :where(a:hover) { text-decoration-color: currentColor; }
  .ds :where(strong, b) { font-weight: var(--w-strong); color: var(--fg); }
  .ds :where(button, input, select, textarea) { font: inherit; color: inherit; }
  .ds :where(:focus-visible) { outline: 2px solid var(--focus); outline-offset: 2px; border-radius: 3px; }
}

/* ── Grounds: the only place colours are assigned to roles ──────────── */
@layer ds.grounds {
  .ds, .ds [data-ground="paper"], .ds [data-ground="desk"] {
    --bg: var(--paper); --fg: var(--ink); --fg-2: var(--ink-2);
    --line: var(--ink); --line-2: var(--rule); --line-3: var(--rule-2);
    --card: var(--paper);
    --link: var(--ink); --link-line: var(--rule-2);
    --pen-c: var(--pen); --focus: var(--ink);
    --btn: var(--ink); --btn-fg: var(--paper); --btn-hov: #1e293b;
    --chip: var(--desk); --chip-on: var(--ink); --chip-on-fg: var(--paper);
    --num: var(--ink);
  }
  .ds [data-ground="desk"] { --bg: var(--desk); --chip: var(--paper); }
  .ds [data-ground="ink"], .ds .footer {
    --bg: var(--ink); --fg: #f8fafc; --fg-2: #a3b1c6;
    --line: #f8fafc; --line-2: #1e293b; --line-3: #334155;
    --card: var(--paper);
    --link: #f8fafc; --link-line: #64748b;
    --pen-c: var(--pen-on-ink); --focus: var(--hl);
    --btn: var(--paper); --btn-fg: var(--ink); --btn-hov: #e2e8f0;
    --chip: #1e293b; --chip-on: var(--paper); --chip-on-fg: var(--ink);
    --num: var(--hl);
  }
  /* Sky: light blue with navy, the CTA band Vicente picked (15 Oct 2026) */
  .ds [data-ground="sky"] {
    --bg: var(--sky); --fg: var(--sky-ink); --fg-2: var(--sky-ink-2);
    --line: var(--sky-ink); --line-2: #93c5fd; --line-3: #60a5fa;
    --card: var(--paper);
    --link: var(--sky-ink); --link-line: var(--sky-ink-2);
    --pen-c: var(--sky-ink); --focus: var(--sky-ink);
    --btn: var(--ink); --btn-fg: var(--paper); --btn-hov: #1e293b;
    --chip: #dbeafe; --chip-on: var(--ink); --chip-on-fg: var(--paper);
    --num: var(--sky-ink);
  }
  .ds [data-ground="hl"] {
    --bg: var(--hl); --fg: var(--ink); --fg-2: #4a4430;
    --line: var(--ink); --line-2: #e8c93a; --line-3: #c9ac22;
    --card: var(--paper);
    --link: var(--ink); --link-line: var(--ink);
    --pen-c: var(--ink); --focus: var(--ink);
    --btn: var(--ink); --btn-fg: #f8fafc; --btn-hov: #1e293b;
    --chip: #ffeb85; --chip-on: var(--ink); --chip-on-fg: #f8fafc;
    --num: var(--ink);
  }
  /* A ground paints itself and resets text to its own roles */
  .ds, .ds [data-ground], .ds .footer { background-color: var(--bg); color: var(--fg); }
  /* Cards and fields are always paper, whatever they sit on */
  .ds :is(.ds-teacher, .ds-search, .ds-field input, .ds-field select, .ds-field textarea) {
    --fg: var(--ink); --fg-2: var(--ink-2); --line: var(--ink); --line-2: var(--rule); --line-3: var(--rule-2);
    --link: var(--ink); --link-line: var(--rule-2); --pen-c: var(--pen); --focus: var(--ink);
    --btn: var(--ink); --btn-fg: var(--paper); --btn-hov: #1e293b; --num: var(--ink);
    background-color: var(--card); color: var(--fg);
  }
}

/* ── Layout ─────────────────────────────────────────────────────────── */
@layer ds.layout {
  .ds .ds-wrap { width: 100%; max-width: calc(var(--max) + 2 * var(--gutter)); margin-inline: auto; padding-inline: var(--gutter); }
  .ds .ds-section { padding-block: var(--s-8); }
  @media (min-width: 768px) { .ds .ds-section { padding-block: var(--s-9); } }
  .ds .ds-head { display: grid; gap: var(--s-3); align-content: start; margin-bottom: var(--s-6); max-width: 46rem; }
  .ds .ds-head p { color: var(--fg-2); font-size: var(--t-lead); line-height: 1.5; }
  .ds .ds-grid { display: grid; gap: var(--s-5); grid-template-columns: 1fr; }
  @media (min-width: 640px) { .ds .ds-grid--2, .ds .ds-grid--3 { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
  @media (min-width: 1024px) { .ds .ds-grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
  .ds .ds-row { display: flex; flex-wrap: wrap; gap: var(--s-3); align-items: center; }
}

/* ── Components ─────────────────────────────────────────────────────── */
@layer ds.components {

  /* Label: small caps line, like the heading of an index card */
  .ds .ds-label { font-size: var(--t-label); font-weight: 600; letter-spacing: .12em; text-transform: uppercase; color: var(--fg-2); }
  .ds .ds-lead { font-size: var(--t-lead); line-height: 1.5; color: var(--fg-2); max-width: 38rem; }
  .ds .ds-muted { color: var(--fg-2); }

  /* Highlighter: one light hand pass over the lower part of the word.
     Text on it is always ink, whatever the ground. */
  .ds mark.ds-hl {
    color: var(--ink);
    background-color: transparent;
    background-repeat: no-repeat;
    background-size: 100% 62%;
    background-position: 0 82%;
    padding: 0 .1em;
    margin: 0 -.05em;
    -webkit-box-decoration-break: clone;
    box-decoration-break: clone;
    background-image: var(--hl-stroke);
  }
  .ds mark.ds-hl--b { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 40' preserveAspectRatio='none'%3E%3Cpath d='M1 7c55 1 110-3 160 0 15 1 28 2 37 4l-3 23c-46 2-102 4-150 3-15 0-30-1-42-3z' fill='%23FFE14D' fill-opacity='.9'/%3E%3C/svg%3E"); }
  .ds mark.ds-hl--c { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 40' preserveAspectRatio='none'%3E%3Cpath d='M5 12c46-6 97-5 146-7 18 0 32 1 45 4l1 22c-55 6-122 5-189 4l-6-9z' fill='%23FFE14D' fill-opacity='.9'/%3E%3C/svg%3E"); }
  /* On ink, any letter part outside the stroke would vanish: full-height pass */
  .ds [data-ground="ink"] mark.ds-hl { background-size: 100% 100%; background-position: center; padding: .04em .14em; background-image: var(--hl-stroke-full); }
  /* On a yellow ground the highlighter would vanish: a fine ink underline */
  .ds [data-ground="hl"] mark.ds-hl { background-image: none; color: var(--ink); text-decoration: underline; text-decoration-thickness: .06em; text-underline-offset: .14em; }

  /* Button: ink block, small radius, no shadow */
  .ds .ds-btn, .ds .btn {
    display: inline-flex; align-items: center; justify-content: center; gap: var(--s-2);
    min-height: 46px; padding: 0 var(--s-5);
    background: var(--btn); color: var(--btn-fg);
    border: var(--hair) solid var(--btn); border-radius: var(--r);
    font-weight: 500; font-size: .9375rem; line-height: 1.2; letter-spacing: 0; text-align: center;
    text-decoration: none; cursor: pointer; padding-block: .5rem; max-width: 100%; text-wrap: balance;   /* long labels wrap on phones instead of widening the page */
    transition: background-color .15s var(--ease), border-color .15s var(--ease), color .15s var(--ease);
  }
  .ds .ds-btn:hover, .ds .btn:hover { background: var(--btn-hov); border-color: var(--btn-hov); color: var(--btn-fg); }
  .ds .ds-btn--ghost { background: transparent; color: var(--fg); border-color: var(--line-3); }
  .ds .ds-btn--ghost:hover { background: transparent; border-color: var(--line); color: var(--fg); }
  .ds .ds-btn--block { width: 100%; }
  .ds .btn-sm { min-height: 38px; padding: 0 var(--s-4); font-size: .875rem; }
  .ds .ds-btn svg, .ds .btn svg { width: 14px; height: 14px; flex: none; transition: transform .15s var(--ease); }
  .ds .ds-btn:hover svg, .ds .btn:hover svg { transform: translateX(2px); }

  /* Text link with an arrow, for "Ver perfil →" style actions */
  .ds .ds-go { display: inline-flex; align-items: center; gap: .35em; font-weight: 500; color: var(--link); text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: .22em; text-decoration-color: var(--link-line); }
  .ds .ds-go:hover { text-decoration-color: currentColor; }

  /* Seal: the logo rosette, inline next to a record */
  .ds .ds-seal { display: inline-flex; align-items: center; gap: .35em; color: var(--pen-c); font-weight: 500; font-size: .8125rem; line-height: 1; white-space: nowrap; letter-spacing: .01em; }
  .ds .ds-seal svg { width: 1.15em; height: 1.15em; }
  /* Teacher card: an index card with a subject tab. No avatar: the
     subject, the name and the title they showed us carry the card. */
  .ds .ds-teacher {
    position: relative; display: flex; flex-direction: column; gap: var(--s-2);
    margin-top: 1.5rem; padding: var(--s-5);
    border: var(--hair) solid var(--rule-2); border-radius: 0 var(--r-lg) var(--r-lg) var(--r-lg);
    text-decoration: none; transition: border-color .15s var(--ease), box-shadow .15s var(--ease);
  }
  .ds a.ds-teacher:hover { border-color: var(--ink); box-shadow: var(--soft); }
  .ds a.ds-teacher:hover .ds-teacher__tab { border-color: var(--ink); }
  .ds .ds-teacher__tab {
    position: absolute; left: calc(-1 * var(--hair)); bottom: 100%;
    max-width: calc(100% - 2rem); padding: .28rem .7rem .22rem;
    background: var(--hl); color: var(--ink);
    border: var(--hair) solid var(--rule-2); border-bottom: 0; border-radius: var(--r) var(--r) 0 0;
    font-size: var(--t-label); font-weight: 600; letter-spacing: .1em; text-transform: uppercase;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
    transition: border-color .15s var(--ease);
  }
  .ds .ds-teacher__name { font-family: var(--font-display); font-size: 1.375rem; font-weight: 500; letter-spacing: -.018em; line-height: 1.15; color: var(--fg); }
  .ds .ds-teacher__title { font-size: var(--t-small); color: var(--fg); padding-bottom: var(--s-3); border-bottom: var(--hair) solid var(--rule); }
  .ds .ds-teacher__facts { display: grid; gap: 2px; padding-top: var(--s-1); font-size: var(--t-small); color: var(--fg-2); }
  .ds .ds-teacher__facts dt { display: inline; font-weight: 500; color: var(--fg); }
  .ds .ds-teacher__facts dd { display: inline; margin: 0; }
  .ds .ds-teacher__foot { display: flex; justify-content: space-between; align-items: center; gap: var(--s-3); margin-top: auto; padding-top: var(--s-4); font-size: var(--t-small); }

  /* Video hero: full screen, the shared nav inside (transparent), one big
     headline, the two doors (.ds-choices). Video: a <video> in .ds-vhero__media;
     the page picks the cut (16:9 / 9:16) and serves the poster to reduced
     motion and Save-Data. Always on the ink ground. */
  .ds .ds-vhero { position: relative; min-height: 100svh; display: grid; grid-template-rows: auto 1fr; overflow: hidden; isolation: isolate; }
  .ds .ds-vhero .nav { position: relative; background: transparent; border-bottom: 0; }
  .ds .ds-vhero__media { position: absolute; inset: 0; z-index: -1; background: var(--ink) center / cover no-repeat; }
  .ds .ds-vhero__media video { width: 100%; height: 100%; object-fit: cover; }
  .ds .ds-vhero__media::after { content: ""; position: absolute; inset: 0; background: linear-gradient(180deg, rgba(15,23,42,.55) 0%, rgba(15,23,42,.15) 30%, rgba(15,23,42,.25) 60%, rgba(15,23,42,.8) 100%); }
  .ds .ds-vhero__body { align-self: end; display: grid; justify-items: center; text-align: center; gap: var(--s-6); padding-bottom: clamp(48px, 10vh, 112px); }
  .ds .ds-vhero h1 { font-size: clamp(3rem, 10.5vw, 10rem); font-weight: 500; letter-spacing: -.05em; line-height: .92; max-width: 14ch; }
  .ds .ds-vhero__where { display: block; margin-top: 1.1em; font-size: clamp(1rem, 1.6vw, 1.375rem); font-weight: 500; letter-spacing: .14em; text-transform: uppercase; color: var(--fg); }
  /* The highlighter swipes in once: the word starts white (readable on the
     dark hero) and turns ink as the stroke crosses it, so it is legible at
     every frame. */
  .ds .ds-vhero h1 mark.ds-hl { display: inline-block; line-height: .92; padding: .03em .1em .07em; margin: .04em -.04em 0; background-size: 100% 100%; background-position: left center; animation: ds-swipe .9s cubic-bezier(.6,0,.2,1) .5s backwards; }
  @keyframes ds-swipe { from { background-size: 0% 100%; color: var(--fg); } 40% { color: var(--fg); } to { background-size: 100% 100%; color: var(--ink); } }

  /* Choices: the two doors under the hero headline (families /buscar/,
     teachers /soy-profesor/, the home with the iPhone demo). Glass on the video
     hero; the main door is solid paper. */
  .ds .ds-choices { display: grid; gap: var(--s-3); width: min(100%, 520px); }
  @media (min-width: 640px) { .ds .ds-choices { grid-template-columns: 1fr 1fr; } }
  .ds .ds-choices a { display: flex; align-items: center; justify-content: space-between; gap: var(--s-4); min-height: 60px; padding: 0 var(--s-5); border-radius: var(--r-lg); font-size: 1.125rem; font-weight: 500; text-decoration: none; color: var(--fg); border: var(--hair) solid var(--line-3); transition: background-color .15s var(--ease), border-color .15s var(--ease), color .15s var(--ease); }
  .ds .ds-choices a svg { width: 18px; height: 18px; flex: none; transition: transform .15s var(--ease); }
  .ds .ds-choices a:hover svg { transform: translateX(3px); }
  .ds .ds-choices a:hover { border-color: var(--line); }
  .ds .ds-choices .ds-choices__main { background: var(--btn); color: var(--btn-fg); border-color: var(--btn); }
  .ds .ds-choices .ds-choices__main:hover { background: var(--hl); border-color: var(--hl); color: var(--ink); }
  .ds .ds-vhero .ds-choices a:not(.ds-choices__main) { background: rgba(15,23,42,.25); border-color: rgba(248,250,252,.55); -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px); }

  /* Search: one hairline bar of fields; stacks on the phone */
  .ds .ds-search { display: grid; border: var(--hair) solid var(--rule-2); border-radius: var(--r-lg); box-shadow: var(--soft); overflow: hidden; }
  .ds .ds-search__f { display: grid; gap: 2px; padding: var(--s-3) var(--s-4); border-bottom: var(--hair) solid var(--line-2); position: relative; }
  .ds .ds-search__f span { font-size: var(--t-label); font-weight: 600; letter-spacing: .12em; text-transform: uppercase; color: var(--fg-2); }
  .ds .ds-search__f select {
    appearance: none; -webkit-appearance: none; width: 100%; padding: 2px 1.25rem 2px 0; text-overflow: ellipsis; border: 0; background: transparent;
    font-size: 1rem; color: var(--fg); cursor: pointer;
    background: no-repeat right center / 12px url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M3 6l5 5 5-5' fill='none' stroke='%230f172a' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  }
  .ds .ds-search__f select:focus { outline: none; }
  .ds .ds-search__f:focus-within { background: #fffbe0; }
  .ds .ds-search__go { margin: var(--s-3); }
  @media (min-width: 768px) {
    .ds .ds-search { grid-template-columns: 1fr 1fr 1fr auto; align-items: center; }
    .ds .ds-search__f { border-bottom: 0; border-right: var(--hair) solid var(--line-2); padding: var(--s-3) var(--s-4) var(--s-3) var(--s-5); }
    .ds .ds-search__f:nth-child(3) { border-right: 0; }
    .ds .ds-search__go { margin: 0 var(--s-2) 0 0; }
  }
  /* Live count under the search */
  .ds .ds-count { display: flex; flex-wrap: wrap; gap: var(--s-2) var(--s-4); align-items: baseline; margin-top: var(--s-3); font-size: var(--t-small); color: var(--fg-2); }
  .ds .ds-count b { color: var(--fg); font-weight: 600; font-variant-numeric: tabular-nums; }

  /* Steps: big numbers (01, 02, 03) above a short title and line, as on
     the v6 navy section Vicente liked; yellow on navy, navy elsewhere */
  .ds .ds-steps { display: grid; gap: var(--s-6); counter-reset: ds-step; }
  @media (min-width: 768px) { .ds .ds-steps { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--s-6); } }
  .ds .ds-step { display: grid; gap: var(--s-2); align-content: start; counter-increment: ds-step; padding-top: var(--s-5); border-top: var(--hair) solid var(--line-3); }
  .ds .ds-step::before { content: counter(ds-step, decimal-leading-zero); font-size: clamp(2.75rem, 3.5vw + 1rem, 4rem); font-weight: 700; letter-spacing: -.045em; line-height: 1; color: var(--num); margin-bottom: var(--s-3); font-variant-numeric: tabular-nums; }
  .ds .ds-step h3 { font-size: 1.25rem; font-weight: 600; }
  .ds .ds-step p { color: var(--fg-2); }

  /* Link list: ruled rows, like lines in a notebook */
  .ds .ds-list { border-top: var(--hair) solid var(--line-3); }
  .ds .ds-list li { border-bottom: var(--hair) solid var(--line-2); }
  .ds .ds-list a { display: flex; justify-content: space-between; align-items: baseline; gap: var(--s-4); padding: var(--s-4) 0; color: var(--fg); text-decoration: none; font-weight: 500; }
  .ds .ds-list a span { font-weight: 400; color: var(--fg-2); font-size: var(--t-small); white-space: nowrap; }
  .ds .ds-list a:hover { text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: .22em; }

  /* FAQ: native details/summary; answers stay in the HTML for crawlers */
  .ds .ds-faq { border-top: var(--hair) solid var(--line-3); }
  .ds .ds-faq details { border-bottom: var(--hair) solid var(--line-2); }
  .ds .ds-faq summary { display: flex; justify-content: space-between; gap: var(--s-4); padding: var(--s-4) 0; cursor: pointer; list-style: none; font-weight: 500; line-height: 1.4; color: var(--fg); }
  .ds .ds-faq summary::-webkit-details-marker { display: none; }
  .ds .ds-faq summary::after { content: "+"; flex: none; font-size: 1.25rem; line-height: 1; font-weight: 300; color: var(--pen-c); transition: transform .15s var(--ease); }
  .ds .ds-faq details[open] summary::after { transform: rotate(45deg); }
  .ds .ds-faq details > :not(summary) { padding: 0 0 var(--s-5); color: var(--fg-2); max-width: 42rem; font-size: .9375rem; }

  /* Band: a full-width call to action on its own ground */
  .ds .ds-band { padding-block: var(--s-7); }
  .ds .ds-band .ds-wrap { display: grid; gap: var(--s-5); align-items: center; }
  .ds .ds-band h2 { font-size: clamp(1.5rem, 1.8vw + 1rem, 2.125rem); }
  .ds .ds-band p { color: var(--fg-2); margin-top: var(--s-2); max-width: 36rem; }
  @media (min-width: 768px) { .ds .ds-band .ds-wrap { grid-template-columns: 1fr auto; gap: var(--s-7); } }

  /* Form field */
  .ds .ds-field { display: grid; gap: var(--s-2); align-content: start; }
  .ds .ds-field > label { font-weight: 500; font-size: var(--t-small); color: var(--fg); }
  .ds .ds-field :is(input, select, textarea) {
    width: 100%; min-height: 46px; padding: .65rem .85rem;
    border: var(--hair) solid var(--rule-2); border-radius: var(--r);
    font-size: 1rem; line-height: 1.3;
    transition: border-color .15s var(--ease), box-shadow .15s var(--ease);
  }
  .ds .ds-field select { appearance: none; -webkit-appearance: none; padding-right: 2.5rem; background: var(--card) no-repeat right .85rem center / 12px url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M3 6l5 5 5-5' fill='none' stroke='%230f172a' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E"); }
  .ds .ds-field :is(input, select, textarea):hover { border-color: var(--ink-2); }
  .ds .ds-field :is(input, select, textarea):focus { outline: none; border-color: var(--ink); box-shadow: 0 0 0 3px var(--hl); }
  .ds .ds-field small { color: var(--fg-2); font-size: .8125rem; }
  .ds .ds-field--error :is(input, select, textarea) { border-color: var(--ink); border-width: 2px; }
  .ds .ds-field--error small { color: var(--fg); font-weight: 500; }
  .ds .ds-field--error small::before { content: "! "; font-weight: 700; }

  /* Shared chrome. The nav and footer markup comes from components/nav.html
     and components/footer.html (propagated by build-nav.js / build-footer.js);
     on ds pages the system styles that same markup. */
  .ds .skip-to-content { position: absolute; left: -9999px; top: var(--s-2); z-index: var(--ds-layer-toast); padding: var(--s-2) var(--s-4); background: var(--paper); color: var(--ink); border-radius: var(--r); }
  .ds .skip-to-content:focus { left: var(--s-4); }
  .ds .nav { position: sticky; top: 0; z-index: var(--ds-layer-nav); background: var(--bg); border-bottom: var(--hair) solid var(--line-2); }
  .ds .nav-inner { display: flex; align-items: center; justify-content: space-between; gap: var(--s-4); min-height: 64px; width: 100%; max-width: calc(var(--max) + 2 * var(--gutter)); margin-inline: auto; padding-inline: var(--gutter); }
  .ds .logo { display: inline-flex; align-items: center; gap: 7px; color: var(--fg); text-decoration: none; font-size: 1rem; letter-spacing: -.015em; white-space: nowrap; }
  .ds .logo-mark { width: 22px; height: 22px; flex: none; color: var(--fg); }
  .ds .logo-mark svg { width: 100%; height: 100%; }
  .ds .logo-platform { font-weight: 600; color: var(--fg); }
  .ds .logo-tld { font-weight: 400; color: var(--fg-2); margin-left: -7px; }   /* one word with the name: cancel the flex gap */

  /* Footer: always on ink */
  .ds .footer { padding-block: var(--s-8) var(--s-6); font-size: var(--t-small); }
  .ds .footer .container { width: 100%; max-width: calc(var(--max) + 2 * var(--gutter)); margin-inline: auto; padding-inline: var(--gutter); }
  .ds .footer-inner { display: grid; gap: var(--s-7); }
  .ds .footer-links { display: grid; gap: var(--s-6); grid-template-columns: repeat(2, minmax(0, 1fr)); }
  @media (min-width: 900px) { .ds .footer-inner { grid-template-columns: 1.3fr 2fr; } .ds .footer-links { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
  .ds .footer-brand-tagline { color: var(--fg-2); max-width: 26rem; margin-top: var(--s-3); }
  .ds .footer-col { display: grid; gap: var(--s-2); align-content: start; }
  .ds .footer-col-title { font-size: var(--t-label); font-weight: 600; letter-spacing: .12em; text-transform: uppercase; color: var(--fg-2); margin-bottom: var(--s-1); }
  .ds .footer-col a { color: var(--fg); text-decoration: none; }
  .ds .footer-col a:hover { text-decoration: underline; text-decoration-color: var(--link-line); }
  .ds .footer-bottom { display: flex; flex-wrap: wrap; justify-content: space-between; gap: var(--s-2) var(--s-5); margin-top: var(--s-7); padding-top: var(--s-5); border-top: var(--hair) solid var(--line-2); color: var(--fg-2); }
}

/* ── Legacy bridge: pages whose own CSS predates v7 ─────────────────── */
@layer ds.legacy {

  /* <body class="ds page-legacy"> (guides and one-off pages, migrated by
     tools/migrate-legacy-to-ds.js). Their own <style> still draws their
     components; it reads the old token names, which here point at the
     brand: accent = navy ink, success/warning = ink/slate, small radii,
     soft shadows, Schibsted. No red, no green, no amber (Vicente). */
  .ds.page-legacy {
    --font: "Schibsted Grotesk", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
    --accent: #0f172a; --accent-hov: #1e293b; --accent-lt: #eef2f7;
    --amber: #475569; --amber-dk: #0f172a; --amber-lt: #fffbe6;
    --green: #0f172a; --green-dk: #0f172a; --green-lt: #f1f5f9; --success: #0f172a; --warning: #475569;
    --border: #e2e8f0; --border-sub: #e2e8f0;
    --ink-muted: #475569; --ink-soft: #334155;
    --surface: #ffffff; --surface-soft: #f8fafc; --surface-sub: #f1f5f9;
    --r-sm: 6px; --r-md: 10px; --r-lg: 10px; --r-xl: 12px;
    --sh-sm: 0 1px 2px rgba(15,23,42,.05); --sh-md: 0 1px 2px rgba(15,23,42,.05), 0 8px 24px -12px rgba(15,23,42,.18); --sh-lg: var(--sh-md); --sh-glow: none;
    --pv-blue: #0f172a; --pv-blue-deep: #1e40af; --pv-blue-ink: #0b1f5c; --pv-sky: #bfdbfe; --pv-sky-text: #dbeafe;
    --pv-ink: #0f172a; --pv-ink-2: #334155; --pv-ink-3: #475569; --pv-line: #e2e8f0; --pv-bg-2: #f1f5f9; --pv-night: #0f172a;
    --pv-dark-line: rgba(255,255,255,.14); --pv-dark-text: #a3b1c6; --pv-wa: #25d366; --pv-radius: 6px; --pv-radius-lg: 10px; --pv-max: 1200px; --pv-nav-h: 64px;
    --ds-space-01: .125rem; --ds-space-02: .25rem; --ds-space-03: .5rem; --ds-space-04: .75rem; --ds-space-05: 1rem; --ds-space-06: 1.5rem;
    --ds-space-07: 2rem; --ds-space-08: 2.5rem; --ds-space-09: 3rem; --ds-space-10: 4rem; --ds-space-11: 5rem; --ds-space-12: 6rem; --ds-space-13: 10rem;
    --ds-transition-base: 250ms; --ds-transition-expansion: 300ms;
    --ds-ease-standard: cubic-bezier(.5,0,.1,1); --ds-ease-in: cubic-bezier(.25,0,1,1); --ds-ease-out: cubic-bezier(0,0,.25,1);
    --ds-ease-productive-standard: cubic-bezier(.2,0,.38,.9); --ds-motion-fast-02: 110ms; --ds-motion-moderate-01: 150ms; --ds-motion-moderate-02: 240ms;
    --cmax: 1160px; --cnarrow: 780px;
  }
  /* Dark boxes drawn by the old pages (background: var(--ink)): there the
     accent is the highlighter, so links and checks stay visible (yellow on
     navy, the approved combo) */
  .ds.page-legacy :is(.key-takeaways) { --accent: var(--hl); --accent-hov: #fff3a6; --accent-lt: rgba(255,225,77,.14); --ink-muted: #a3b1c6; }
  /* Old pages paint their own dark sections and expect text to inherit:
     headings, links and bold text follow the colour around them here */
  .ds.page-legacy :where(main) :where(h1, h2, h3, h4, strong, b, a:not([class*="btn"])) { color: inherit; }
  /* Button reset the legacy pages relied on (it lived in site-chrome.css):
     without it a page's unstyled parts (the guides' FAQ toggles) showed the
     browser's grey with a 2px outset border. Zero specificity, layered:
     any page rule still wins. System buttons are excluded: this layer comes
     after ds.components, so it would beat .btn (design audit, 16 Oct 2026). */
  .ds.page-legacy :where(button:not([class*="btn"])) { background: none; border: 0; padding: 0; cursor: pointer; }
  .ds.page-legacy .container { width: 100%; max-width: calc(var(--cmax) + 2 * var(--gutter)); margin-inline: auto; padding-inline: var(--gutter); }
  .ds.page-legacy .content-narrow { width: 100%; max-width: calc(var(--cnarrow) + 2 * var(--gutter)); margin-inline: auto; padding-inline: var(--gutter); }
  .ds.page-legacy .btn-secondary { display: inline-flex; align-items: center; justify-content: center; gap: var(--s-2); min-height: 46px; padding: 0 var(--s-5); background: transparent; color: var(--fg); border: var(--hair) solid var(--line-3); border-radius: var(--r); font-weight: 500; text-decoration: none; }
  .ds.page-legacy .btn-secondary:hover { border-color: var(--line); }
  .ds.page-legacy .btn-arrow { width: 14px; height: 14px; }

  /* Utilities the old pages use */
  .ds.page-legacy :is(.link-accent, .link-ink) { color: var(--ink); font-weight: 500; text-decoration: underline; text-decoration-color: var(--hl-deep); text-decoration-thickness: 2px; text-underline-offset: .2em; }
  .ds.page-legacy .link-inherit { color: inherit; text-decoration: underline; text-underline-offset: 2px; }
  .ds.page-legacy .link-callout { color: var(--hl); text-decoration: underline; }
  .ds.page-legacy .text-ink { color: var(--ink); }
  .ds.page-legacy .text-muted { color: var(--ink-2); }
  .ds.page-legacy .text-accent-bold { color: var(--ink); font-weight: 600; }
  .ds.page-legacy .text-center { text-align: center; }
  .ds.page-legacy .mb-0 { margin-bottom: 0; } .ds.page-legacy .mb-3 { margin-bottom: 1.5rem; } .ds.page-legacy .mb-4 { margin-bottom: 1.25rem; } .ds.page-legacy .mb-5 { margin-bottom: 1.75rem; }
  .ds.page-legacy .mt-3 { margin-top: 1.5rem; } .ds.page-legacy .mt-4 { margin-top: 3rem; }
  .ds.page-legacy .is-hidden { display: none; }
  .ds.page-legacy .honeypot { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
  .ds.page-legacy :is(.table-wrap, .table-wrap--end) { overflow-x: auto; border: var(--hair) solid var(--rule); border-radius: var(--r-lg); margin: 1.25rem 0; }
  .ds.page-legacy .table-wrap--end { margin-bottom: 2rem; }
  .ds.page-legacy .guide-hero-img { display: block; width: 100%; height: auto; margin-bottom: 2rem; border-radius: var(--r-lg); }
  .ds.page-legacy .tiny-note { font-size: .8125rem; color: var(--ink-2); margin: .75rem 0 0; }
  .ds.page-legacy .section-lead { font-size: 1.0625rem; color: var(--ink-2); max-width: 680px; line-height: 1.7; }
  .ds.page-legacy .pos-rel-z1 { position: relative; z-index: 1; }
  .ds.page-legacy .sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
  /* Quick answer: no box and no side bar (a stock pattern, Vicente 16 Oct);
     a lead paragraph whose key words get the highlighter pass */
  .ds.page-legacy .answer-box { margin: 1.5rem 0; padding: 0; background: none; border: 0; font-size: 1.125rem; line-height: 1.65; color: var(--ink-2); max-width: 46rem; }
  .ds.page-legacy .answer-box p { margin: 0; }
  .ds.page-legacy .answer-box strong { color: var(--ink); font-weight: 600; background: no-repeat 0 82% / 100% 62% var(--hl-stroke); padding: 0 .1em; margin: 0 -.05em; -webkit-box-decoration-break: clone; box-decoration-break: clone; }
  .ds.page-legacy .breadcrumb { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-2); font-size: var(--t-small); color: var(--ink-2); }
  .ds.page-legacy .breadcrumb a { color: var(--ink-2); text-decoration: underline; text-decoration-color: var(--rule-2); text-underline-offset: .2em; }
  .ds.page-legacy .breadcrumb-sep { color: var(--ink-2); }

  /* Guides: titles and reading column for both guide templates */
  .ds.page-legacy :is(.article-title, .guia-hero h1) { font-size: clamp(2rem, 4.5vw, 3rem); font-weight: 600; line-height: 1.08; letter-spacing: -.03em; color: var(--ink); margin-bottom: 1rem; max-width: 820px; text-wrap: balance; }
  .ds.page-legacy :is(.prose, .guia-body) h2 { font-size: clamp(1.5rem, 3vw, 2rem); font-weight: 600; line-height: 1.2; letter-spacing: -.022em; color: var(--ink); margin: 3rem 0 .75rem; scroll-margin-top: 96px; }
  .ds.page-legacy :is(.prose, .guia-body) h3 { font-size: 1.25rem; font-weight: 600; line-height: 1.3; letter-spacing: -.015em; color: var(--ink); margin: 2rem 0 .5rem; }
  .ds.page-legacy :is(.prose, .guia-body) :is(p, li) { font-size: 1.0625rem; line-height: 1.75; color: var(--ink-2); }
  .ds.page-legacy :is(.prose, .guia-body) p { margin: 0 0 1rem; }
  .ds.page-legacy :is(.prose, .guia-body) li { margin-bottom: .25rem; }
  .ds.page-legacy :is(.prose, .guia-body) a:not([class]) { color: var(--ink); text-decoration-color: var(--hl-deep); text-decoration-thickness: 2px; }

  /* The main CTA inside a guide: the sky band */
  .ds.page-legacy :is(.cta-strip, .inline-cta) { margin: 3rem 0; padding: 2.5rem 1.5rem; background: var(--sky); border: 0; border-radius: var(--r-lg); text-align: center; color: var(--sky-ink); }
  .ds.page-legacy :is(.cta-strip h2, .cta-strip h3, .cta-strip-title, .inline-cta h3) { font-size: clamp(1.375rem, 3vw, 1.75rem); font-weight: 600; letter-spacing: -.022em; line-height: 1.15; color: var(--sky-ink); margin: 0 0 .75rem; }
  .ds.page-legacy :is(.cta-strip p, .cta-strip-sub, .inline-cta p) { font-size: 1rem; line-height: 1.6; color: var(--sky-ink-2); max-width: 520px; margin: 0 auto 1.5rem; }
  .ds.page-legacy :is(.cta-strip, .inline-cta) .btn { background: var(--ink); color: var(--paper); border-color: var(--ink); }
  .ds.page-legacy :is(.cta-strip, .inline-cta) .btn:hover { background: #1e293b; color: var(--paper); }
  /* Cross-audience strip ("¿Eres profesor?" in a family guide): quieter */
  .ds.page-legacy :is(.teacher-strip, .student-strip) { margin: 2.5rem 0; padding: 1.5rem; background: var(--desk); border: var(--hair) solid var(--rule); border-radius: var(--r-lg); text-align: center; }
  .ds.page-legacy :is(.teacher-strip, .student-strip) p { font-size: .9375rem; line-height: 1.6; color: var(--ink-2); margin: 0 0 .75rem; }
  .ds.page-legacy :is(.teacher-strip, .student-strip) :is(.btn, .btn-secondary) { background: var(--paper); color: var(--ink); border: var(--hair) solid var(--rule-2); }
  /* Button beside the table of contents */
  .ds.page-legacy .toc-cta { margin-top: 1.5rem; padding-top: 1.5rem; border-top: var(--hair) solid var(--rule); }
  .ds.page-legacy .toc-cta-btn { display: flex; align-items: center; justify-content: center; gap: .5rem; min-height: 44px; padding: 0 1rem; background: var(--ink); color: var(--paper); font-weight: 500; font-size: .875rem; border-radius: var(--r); text-decoration: none; }
  .ds.page-legacy .toc-cta-btn:hover { background: #1e293b; }
  .ds.page-legacy .toc-cta-note { font-size: .75rem; color: var(--ink-2); text-align: center; margin-top: .5rem; }
}

/* ── Templates: page families whose markup predates v7 ─────────────── */
@layer ds.templates {

  /* Hubs: /profesores-particulares/ and its subject, city and L2 pages
     (<body class="ds page-hub">). Colours come from the grounds the
     migration put on the sections: hero = ink, tutors = desk, CTA = sky. */
  .ds.page-hub .container { width: 100%; max-width: calc(var(--max) + 2 * var(--gutter)); margin-inline: auto; padding-inline: var(--gutter); }
  .ds.page-hub .content-narrow { width: 100%; max-width: calc(46rem + 2 * var(--gutter)); margin-inline: auto; padding-inline: var(--gutter); }
  .ds.page-hub .content-section { padding-block: var(--s-8); }
  .ds.page-hub .content-section + .content-section[data-ground="paper"], .ds.page-hub .content-section:not([data-ground]) + .content-section:not([data-ground]) { padding-top: 0; }

  /* Hero */
  .ds.page-hub .cluster-hero { padding-block: var(--s-8) var(--s-9); }
  .ds.page-hub .cluster-hero-inner { max-width: 50rem; display: grid; gap: var(--s-5); justify-items: start; }
  .ds.page-hub .breadcrumb { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-2); font-size: var(--t-small); color: var(--fg-2); }
  .ds.page-hub .breadcrumb a { color: var(--fg-2); text-decoration: underline; text-decoration-color: var(--line-3); text-underline-offset: .2em; }
  .ds.page-hub .breadcrumb a:hover { color: var(--fg); }
  .ds.page-hub .breadcrumb [aria-current] { color: var(--fg); }
  .ds.page-hub .breadcrumb-sep { color: var(--fg-2); }
  .ds.page-hub .page-label { font-size: var(--t-label); font-weight: 600; letter-spacing: .12em; text-transform: uppercase; color: var(--hl); }
  .ds.page-hub [data-ground]:not([data-ground="ink"]) .page-label { color: var(--fg-2); }
  .ds.page-hub .cluster-hero-title { font-size: clamp(2.25rem, 4.6vw + 1rem, 4rem); font-weight: 600; letter-spacing: -.035em; line-height: 1.02; }
  .ds.page-hub .answer-box { color: var(--fg-2); font-size: var(--t-lead); line-height: 1.6; max-width: 44rem; }
  .ds.page-hub .answer-box strong { color: var(--fg); font-weight: 600; }
  /* On the navy hero, bold phrases can run several lines: plain white, no highlight */

  /* Pillar hero: two doors (families / teachers) */
  .ds.page-hub .hero-dual { display: grid; gap: var(--s-4); width: 100%; }
  @media (min-width: 768px) { .ds.page-hub .hero-dual { grid-template-columns: 1fr 1fr; } }
  .ds.page-hub .hero-block { display: grid; gap: var(--s-2); align-content: start; padding: var(--s-5); border: var(--hair) solid var(--line-3); border-radius: var(--r-lg); }
  .ds.page-hub .hero-block--primary { background: var(--paper); border-color: var(--paper); --fg: var(--ink); --fg-2: var(--ink-2); --btn: var(--ink); --btn-fg: var(--paper); --btn-hov: #1e293b; color: var(--ink); }
  .ds.page-hub .hero-block-label { font-size: var(--t-label); font-weight: 600; letter-spacing: .12em; text-transform: uppercase; color: var(--fg-2); }
  .ds.page-hub .hero-block-title { font-size: 1.25rem; font-weight: 600; color: var(--fg); }
  .ds.page-hub .hero-block p { color: var(--fg-2); }
  .ds.page-hub .hero-block .btn { justify-self: start; margin-top: var(--s-2); }

  /* Reading column */
  .ds.page-hub .section-title { font-size: var(--t-h2); margin-bottom: var(--s-5); }
  .ds.page-hub .sub-title { font-size: var(--t-h3); margin: var(--s-6) 0 var(--s-3); }
  .ds.page-hub .body-text, .ds.page-hub .methodology-body p { color: var(--fg-2); font-size: 1.0625rem; line-height: 1.75; margin-bottom: var(--s-5); }
  .ds.page-hub .body-text strong, .ds.page-hub .methodology-body strong { color: var(--fg); }
  .ds.page-hub .link-accent, .ds.page-hub .link-ink { color: var(--fg); font-weight: 500; text-decoration: underline; text-decoration-color: var(--hl-deep); text-decoration-thickness: 2px; text-underline-offset: .2em; }
  .ds.page-hub .link-accent:hover, .ds.page-hub .link-ink:hover { text-decoration-color: currentColor; }
  .ds.page-hub .text-accent-bold, .ds.page-hub .text-ink { color: var(--fg); font-weight: 600; }
  .ds.page-hub .body-list, .ds.page-hub .materia-list, .ds.page-hub .check-list { list-style: disc; padding-left: var(--s-5); margin-bottom: var(--s-5); color: var(--fg-2); line-height: 1.9; }
  /* Quotes carry their own quotation marks: an indented italic line, no side bar */
  .ds.page-hub blockquote.methodology-body { margin: var(--s-6) 0; padding-left: var(--s-6); border: 0; font-style: italic; font-size: 1.125rem; color: var(--fg); }
  .ds.page-hub .cite-ref { font-size: .75rem; font-weight: 600; vertical-align: super; line-height: 0; color: var(--fg); text-decoration: none; }
  .ds.page-hub .cite-ref:hover { text-decoration: underline; }
  .ds.page-hub .mb-4 { margin-bottom: var(--s-4); }
  .ds.page-hub .mt-3 { margin-top: var(--s-3); }

  /* Numbered lists: big numbers, as in ds-steps */
  .ds.page-hub .step-list, .ds.page-hub .criteria-list { display: grid; gap: var(--s-5); margin: var(--s-6) 0; padding: 0; list-style: none; }
  .ds.page-hub .step-item, .ds.page-hub .criteria-item { display: grid; grid-template-columns: 3.25rem 1fr; gap: var(--s-4); padding-top: var(--s-4); border-top: var(--hair) solid var(--line-2); }
  .ds.page-hub .step-num, .ds.page-hub .criteria-num { font-size: 2rem; font-weight: 700; letter-spacing: -.04em; line-height: 1; color: var(--num); font-variant-numeric: tabular-nums; background: none; width: auto; height: auto; }
  .ds.page-hub .step-body, .ds.page-hub .criteria-body { color: var(--fg-2); }
  .ds.page-hub .step-body strong, .ds.page-hub .criteria-body strong { display: block; color: var(--fg); font-weight: 600; margin-bottom: var(--s-1); }

  /* Tables: hairlines; on phones each row becomes a card (td[data-label]) */
  .ds.page-hub .price-table-wrap { margin: var(--s-6) 0; overflow-x: auto; }
  .ds.page-hub :is(.price-table, .compare-table) { width: 100%; border-collapse: collapse; font-size: .9375rem; }
  .ds.page-hub :is(.price-table, .compare-table) th { text-align: left; padding: var(--s-3) var(--s-4); font-size: var(--t-label); font-weight: 600; letter-spacing: .1em; text-transform: uppercase; color: var(--fg-2); border-bottom: var(--hair) solid var(--line); }
  .ds.page-hub :is(.price-table, .compare-table) td { padding: var(--s-3) var(--s-4); border-bottom: var(--hair) solid var(--line-2); color: var(--fg-2); vertical-align: top; }
  .ds.page-hub :is(.price-table, .compare-table) td:first-child { color: var(--fg); font-weight: 500; }
  .ds.page-hub .compare-table :is(.check, .cross) { font-weight: 600; }
  .ds.page-hub .compare-table .check { color: var(--fg); }
  .ds.page-hub .compare-table .cross { color: var(--fg-2); }
  @media (max-width: 639px) {
    .ds.page-hub :is(.price-table, .compare-table), .ds.page-hub :is(.price-table, .compare-table) tbody { display: block; }
    .ds.page-hub :is(.price-table, .compare-table) thead { display: none; }
    .ds.page-hub :is(.price-table, .compare-table) tr { display: block; margin-bottom: var(--s-4); border: var(--hair) solid var(--line-2); border-radius: var(--r-lg); overflow: hidden; }
    .ds.page-hub :is(.price-table, .compare-table) td { display: flex; justify-content: space-between; gap: var(--s-4); padding: var(--s-3) var(--s-4); }
    .ds.page-hub :is(.price-table, .compare-table) td:last-child { border-bottom: 0; }
    .ds.page-hub :is(.price-table, .compare-table) td::before { content: attr(data-label); flex: none; min-width: 42%; font-size: .8125rem; font-weight: 600; color: var(--fg); }
  }

  /* FAQ (static, answers always visible) */
  .ds.page-hub .faq-list { list-style: none; padding: 0; margin: 0; border-top: var(--hair) solid var(--line-3); }
  .ds.page-hub .faq-item { padding: var(--s-5) 0; border-bottom: var(--hair) solid var(--line-2); }
  .ds.page-hub .faq-question { font-size: 1.0625rem; font-weight: 600; color: var(--fg); margin-bottom: var(--s-2); }
  .ds.page-hub .faq-answer, .ds.page-hub .faq-answer p { color: var(--fg-2); line-height: 1.7; }

  /* Related subjects and cities: index cards */
  .ds.page-hub .related-clusters { display: grid; gap: var(--s-4); grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); margin-top: var(--s-5); }
  .ds.page-hub .cluster-card { display: grid; gap: var(--s-1); align-content: start; padding: var(--s-5); background: var(--card); border: var(--hair) solid var(--rule-2); border-radius: var(--r-lg); text-decoration: none; color: var(--ink); transition: border-color .15s var(--ease), box-shadow .15s var(--ease); }
  .ds.page-hub .cluster-card:hover { border-color: var(--ink); box-shadow: var(--soft); }
  .ds.page-hub .cluster-card-label { font-size: var(--t-label); font-weight: 600; letter-spacing: .12em; text-transform: uppercase; color: var(--ink-2); }
  .ds.page-hub .cluster-card-title { font-size: 1.125rem; font-weight: 600; color: var(--ink); }
  .ds.page-hub .cluster-card-desc { font-size: var(--t-small); color: var(--ink-2); line-height: 1.5; }

  /* Tutor cards (markup from tools/apply-cross-listings.js) */
  .ds.page-hub .tutor-card { display: grid; gap: var(--s-4); padding: var(--s-5); background: var(--card); color: var(--ink); border: var(--hair) solid var(--rule-2); border-radius: var(--r-lg); --fg: var(--ink); --fg-2: var(--ink-2); --btn: var(--ink); --btn-fg: var(--paper); --btn-hov: #1e293b; }
  .ds.page-hub .tutor-card + .tutor-card { margin-top: var(--s-4); }
  .ds.page-hub .tutor-card-header { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: flex-start; gap: var(--s-3); padding-bottom: var(--s-4); border-bottom: var(--hair) solid var(--rule); }
  .ds.page-hub .tutor-card-name { font-size: 1.375rem; font-weight: 600; letter-spacing: -.02em; line-height: 1.15; color: var(--ink); }
  .ds.page-hub .tutor-card-sub { margin-top: var(--s-1); font-size: var(--t-small); color: var(--ink-2); }
  .ds.page-hub .badge-verified { display: inline-flex; align-items: center; gap: .35em; padding: .3rem .6rem; background: var(--hl); color: var(--ink); border-radius: 999px; font-size: .75rem; font-weight: 600; white-space: nowrap; }
  .ds.page-hub .badge-verified svg { width: 14px; height: 14px; }
  .ds.page-hub .tutor-card-meta { display: flex; flex-wrap: wrap; gap: var(--s-2); }
  .ds.page-hub .tutor-tag { padding: .25rem .6rem; border: var(--hair) solid var(--rule-2); border-radius: var(--r); font-size: .8125rem; color: var(--ink-2); }
  .ds.page-hub .tutor-tag--online { border-color: var(--ink); color: var(--ink); }
  .ds.page-hub .tutor-card-cta { display: flex; }

  /* Teacher CTA strip: the sky band */
  .ds.page-hub .cta-strip { padding-block: var(--s-7); }
  .ds.page-hub .cta-strip .container { display: grid; gap: var(--s-2) var(--s-7); align-items: center; }
  .ds.page-hub .cta-strip-title { font-size: clamp(1.5rem, 1.8vw + 1rem, 2.125rem); font-weight: 600; letter-spacing: -.022em; line-height: 1.1; color: var(--fg); }
  .ds.page-hub .cta-strip-sub { color: var(--fg-2); max-width: 36rem; }
  .ds.page-hub .cta-strip .btn { justify-self: start; margin-top: var(--s-3); }
  @media (min-width: 768px) {
    .ds.page-hub .cta-strip .container { grid-template-columns: 1fr auto; }
    .ds.page-hub .cta-strip .container > :not(.btn) { grid-column: 1; }
    .ds.page-hub .cta-strip .btn { grid-column: 2; grid-row: 1 / span 2; margin-top: 0; }
  }

  /* Pillar extras: tools, sources, byline */
  .ds.page-hub .tools-grid { display: grid; gap: var(--s-4); grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); margin: var(--s-6) 0; }
  .ds.page-hub .tool-card { padding: var(--s-5); border: var(--hair) solid var(--line-2); border-radius: var(--r-lg); }
  .ds.page-hub .tool-card-name { font-weight: 600; color: var(--fg); margin-bottom: var(--s-1); }
  .ds.page-hub .tool-card-desc { font-size: var(--t-small); color: var(--fg-2); }
  .ds.page-hub .sources-section { padding-block: var(--s-7); border-top: var(--hair) solid var(--line-2); }
  .ds.page-hub .sources-section h2 { font-size: var(--t-label); font-weight: 600; letter-spacing: .12em; text-transform: uppercase; color: var(--fg-2); margin-bottom: var(--s-4); }
  .ds.page-hub .sources-list { list-style: decimal; padding-left: var(--s-5); display: grid; gap: var(--s-2); font-size: var(--t-small); color: var(--fg-2); }
  .ds.page-hub .byline { display: flex; align-items: center; gap: var(--s-4); margin-top: var(--s-6); padding: var(--s-5); border: var(--hair) solid var(--line-2); border-radius: var(--r-lg); }
  .ds.page-hub .byline-logo { width: 40px; height: 40px; flex: none; color: var(--fg); }
  .ds.page-hub .byline-meta { font-size: var(--t-small); color: var(--fg-2); line-height: 1.5; }
  .ds.page-hub .byline-meta strong { display: block; color: var(--fg); }
  .ds.page-hub .sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
}

/* ── Utilities ──────────────────────────────────────────────────────── */
@layer ds.utilities {
  /* Last layer, so these beat every component without !important */
  .ds [hidden] { display: none; }
  /* Audience swap (CLAUDE.md F5): hidden from view, never display:none,
     so both audiences' content stays in the HTML for crawlers */
  .ds [data-audience][aria-hidden="true"] { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
  @media (prefers-reduced-motion: reduce) { .ds *, .ds *::before, .ds *::after { transition: none; animation: none; } }
}
