/* portal.css — shared styles for the EnjoyChemistry marketing pages
   (index.html / skillsto / videos). Loads AFTER chem-apps/css/base.css,
   which defines --bg, --surface, --text, --text-muted, --border,
   --font, --font-scale, and the [data-theme="dark"] overrides. This file
   only adds portal-specific layout and components on top of those vars.

   Brand accent colors (the 5/6-color "spectrum" used for app-card tinting,
   the games block, and the logo mark) are literal hex values, NOT tied to
   the light/dark axis — they're brand identity, same as the logo mark's
   near-black squircle, and intentionally don't shift with theme.
*/

/* ── Self-hosted webfonts ───────────────────────────────────────────────
   Vendored from the upstream Google Fonts repository under the SIL Open
   Font License 1.1. License texts and a provenance record ship alongside
   the font files in fonts/.

   Self-hosted rather than fetched from Google's CDN, for two reasons:
     1. The suite must render identically with no network at all — flash
        drive, offline classroom, locked-down district machine. A CDN font
        silently falls back to system sans and the layout shifts with it.
     2. A CDN font request transmits the reader's IP address and user-agent
        to a third party on every page load. Nothing else in the platform
        makes an outbound request; this was the last one.

   Full character sets, deliberately NOT subsetted. The suite needs ø
   (Brønsted), en dashes, Δ, °, ⇌ and the grandfathered Unicode subscripts
   in shared data strings — and with no network there is no second chance
   at a missing glyph, it just renders as tofu.

   These are variable fonts: one file covers every weight the suite asks
   for, which is why the per-page weight lists are gone from the <link>
   tags that used to live in each HTML head.
   ────────────────────────────────────────────────────────────────── */
@font-face {
  font-family: "DM Sans";
  src: url("fonts/DMSans-Variable.woff2") format("woff2");
  font-weight: 100 1000;   /* full wght axis */
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "DM Sans";
  src: url("fonts/DMSans-Italic-Variable.woff2") format("woff2");
  font-weight: 100 1000;
  font-style: italic;
  font-display: swap;
}

/* Self-contained theme variables (matching chem-apps/css/base.css's values).
   Duplicated here rather than linked, because Skillsto and Videos ship on
   separate subdomains and can't reliably reach back to the main domain's
   chem-apps/ folder via a relative path. Keeps each portal page standalone. */
/* ── Arrow override ───────────────────────────────────────────────
   Six codepoints only. DM Sans draws its arrowheads as open chevrons with no
   filled triangle; at the 0.9rem of body copy that is about 16px, where the
   chevrons lose their point and read as a lozenge rather than an arrow. Arial
   and Segoe UI fill their heads solid and survive the size. Everything else in
   the suite stays DM Sans — this is a patch, not a font change.

   DECLARED AFTER the main DM Sans faces on purpose: for a shared family, weight
   and style, the last matching declaration wins for the codepoints it claims.

   local() only — nothing is downloaded and nothing new ships. Arial covers
   Windows, macOS and iOS; Arimo is the metric-compatible substitute present on
   ChromeOS. Liberation Sans is deliberately absent: it sits too low on the
   baseline and is no improvement on what it would replace.

   The trailing url() is the safety line. If none of the three local faces
   exist, this falls back to DM Sans explicitly rather than tumbling down the
   stack to whatever sans-serif resolves to — often Liberation or DejaVu on
   Linux. Worst case is therefore exactly today's rendering, never worse.

   Scope notes: the diagonals U+2196-2199 stay with DM Sans, since Arial has no
   glyphs for them. ⇌ ⇄ ⇒ are untouched — never in DM Sans, still falling
   through to the system as they always have. No italic face is declared; no
   italic content currently contains an arrow.
   ─────────────────────────────────────────────────────────────────── */
@font-face {
  font-family: "DM Sans";
  src: local("Arial"), local("Segoe UI"), local("Arimo"),
       url("fonts/DMSans-Variable.woff2") format("woff2");
  unicode-range: U+2190-2195;   /* ← ↑ → ↓ ↔ ↕ */
  font-weight: 100 1000;
  font-style: normal;
}

[data-theme="light"] {
  --bg: #F6F8FB; --surface: #FFFFFF;
  --text: #16202E; --text-muted: #47566A; --text-light: #7C8A9C;
  --border: #E4E9F0; --border-strong: #D9E0E9;
  --portal-primary: #2C5CC5; --portal-primary-light: #EBF0FA;
}
[data-theme="dark"] {
  --bg: #111827; --surface: #1E2636;
  --text: #E5E7EB; --text-muted: #9BA4B4; --text-light: #6B7585;
  --border: #2A3346; --border-strong: #384156;
  --portal-primary: #6B93DB; --portal-primary-light: #1E2C42;
}
:root {
  /* ── Brand geometry ────────────────────────────────────────────────────
     Duplicated from chem-apps/css/base.css on purpose: the subdomains are
     separate origins and cannot reach it. Keep the two in step — if one
     changes, change both, or the app and landing headers drift apart again.
     --bar-inset stops the bar just short of the 't' in 'chemistry', leaving
     'try' hanging. DELIBERATE. 1.34em is the measured advance of 'try' in
     DM Sans Bold at -0.03em tracking: 18.9% of the wordmark. */
  --wordmark-size: 1.3rem;
  --bar: clamp(2px, 0.17rem, 4px);
  --brand-h: calc(var(--wordmark-size) * 1.05 + 0.90rem + 9px + var(--bar));
  --bar-inset: 1.34em;
  --font: "DM Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --font-scale: 1;
  --portal-max: 1240px;
  --brand-blue: #2563EB;   --brand-blue-tint: #EEF3FE;
  --brand-green: #0F9D77;  --brand-green-tint: #E9F7F2;
  --brand-orange: #D2531B; --brand-orange-tint: #FBF1E9;
  --brand-gold: #D19A16;   --brand-gold-tint: #FBF5E6;
  --brand-violet: #6C5CB0; --brand-violet-tint: #F0EEFA;
  --brand-magenta: #CC3399; --brand-magenta-tint: #FBEBF5;
  --logo-mark-bg: #1A1F2B;
}
* { box-sizing: border-box; }
html { font-size: calc(18px * var(--font-scale)); -webkit-font-smoothing: antialiased; }
body { margin: 0; font-family: var(--font); background: var(--bg); color: var(--text); line-height: 1.6; transition: background .2s ease, color .2s ease; }
a { color: var(--brand-blue); text-decoration: none; }
a:hover { text-decoration: underline; }

@keyframes ecBob   { 0%,100% { transform: translateY(0) }        50% { transform: translateY(-5px) } }
@keyframes ecSlide { 0% { transform: translateX(0); opacity: 0 } 18% { opacity: 1 } 82% { opacity: 1 } 100% { transform: translateX(32px); opacity: 0 } }
@keyframes ecPulse { 0%,100% { transform: scale(1); opacity: .45 } 50% { transform: scale(1.28); opacity: 1 } }
@keyframes ecRise  { 0%,100% { height: 20% }                     50% { height: 85% } }

/* ── Header ─────────────────────────────────────────── */
.portal-header { position: sticky; top: 0; z-index: 5; background: var(--surface); border-bottom: 1px solid var(--border); }
.portal-header-inner, .portal-hero-inner, .portal-main, .portal-footer-inner {
  max-width: var(--portal-max); margin: 0 auto; box-sizing: border-box;
}
.portal-header-inner { padding: 0.875rem 2rem; display: flex; align-items: center; justify-content: space-between; gap: 1.5rem; }
.portal-brand, .portal-brand:hover, .portal-brand:focus, .portal-brand:active { display: flex; align-items: center; gap: 0.7rem; text-decoration: none; }
.portal-logo-mark { width: var(--brand-h); height: var(--brand-h); border-radius: 28%; background: var(--logo-mark-bg); position: relative; overflow: hidden; flex: 0 0 auto; }
.portal-logo-mark svg { position: absolute; inset: 0; width: 100%; height: 100%; }
.portal-logo-mark .glyph { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; font-weight: 700; font-size: 1.5rem; line-height: 1; color: #fff; text-shadow: 0 1px 5px rgba(12,16,24,.8); }
.portal-wordmark-group { display: flex; flex-direction: column; align-items: flex-start; gap: 4px; }
/* The lockup is shrink-to-fit, so the bar inside it stretches to exactly the
   wordmark's width — at any font scale, and in the fallback font. The
   subtitle sits OUTSIDE the lockup so a long one cannot stretch the bar. */
.portal-brand-lockup { display: flex; flex-direction: column; align-items: stretch; gap: 5px; }
.portal-wordmark { font-size: var(--wordmark-size); letter-spacing: -.03em; color: var(--text); line-height: 1.05; }
.portal-wordmark .light { font-weight: 400; }
.portal-wordmark .bold { font-weight: 700; }
.portal-header-subtitle { font-size: 0.72rem; font-weight: 500; color: var(--text-light); letter-spacing: .02em; line-height: 1.25; }
.portal-spectrum { display: flex; gap: var(--bar); height: var(--bar); font-size: var(--wordmark-size); margin-right: var(--bar-inset); }
/* flex-basis 12px is a safety net, not decoration: it gives the bar an
   intrinsic width, so if the .portal-brand-lockup wrapper is missing the bar
   renders short rather than vanishing. portal-nav.js injects the wrapper at
   load, after which grow:1 divides the real width evenly as normal. */
.portal-spectrum span { flex: 1 0 12px; border-radius: 2px; }
.portal-nav-links { display: flex; align-items: center; gap: 1.6rem; }
.portal-nav-links a { font-size: 0.85rem; font-weight: 500; color: var(--text-muted); text-decoration: none; }
.portal-nav-links a:hover { color: var(--text); text-decoration: none; }
.portal-header-actions { display: flex; align-items: center; gap: 0.6rem; margin-left: 1.4rem; padding-left: 1.4rem; border-left: 1px solid var(--border); }
/* Matches CoreUI's real .btn-icon.btn-pill exactly (layout.css + base.css var(--radius-sm)/var(--transition)),
   using the suite's default "cobalt" scheme values since the portal doesn't offer a scheme picker. */
.btn-icon { background: none; border: 1px solid var(--border); color: var(--text-muted); border-radius: 8px; padding: 0.3rem 0.5rem; cursor: pointer; font-size: 0.8rem; font-weight: 600; display: inline-flex; align-items: center; gap: 0.25rem; transition: all 200ms cubic-bezier(0.4, 0, 0.2, 1); font-family: var(--font); }
.btn-icon:hover { background: var(--portal-primary-light); color: var(--portal-primary); border-color: var(--portal-primary); }

/* ── Hero ───────────────────────────────────────────── */
.portal-hero { background: var(--surface); border-bottom: 1px solid var(--border); }
.portal-hero-inner { padding: 1.25rem 2rem 1.5rem; display: flex; flex-direction: column; align-items: center; gap: 1rem; text-align: center; }
.portal-pill { display: flex; align-items: center; gap: 8px; padding: 6px 14px; border: 1px solid var(--border); border-radius: 999px; font: 500 0.72rem/1 var(--font); letter-spacing: .1em; text-transform: uppercase; color: var(--text-muted); }
.portal-pill .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--brand-green); display: inline-block; }
.portal-headline { font-size: 3.4rem; font-weight: 700; letter-spacing: -.035em; line-height: 1.05; color: var(--text); max-width: 880px; text-wrap: balance; }
.portal-tagline { font-size: 1.35rem; line-height: 1.5; color: var(--text-muted); max-width: 680px; text-wrap: pretty; }
.portal-tagline .accent { color: var(--brand-blue); font-weight: 500; }
.portal-cta { font-size: 0.95rem; font-weight: 700; color: #fff; background: var(--brand-blue); padding: 0.9rem 1.75rem; border-radius: 11px; text-decoration: none; display: inline-block; }
.portal-cta:hover { text-decoration: none; opacity: 0.92; }

/* ── Sections ───────────────────────────────────────── */
.portal-main { width: 100%; }
.portal-section { padding: 3.5rem 2rem; scroll-margin-top: 80px; }
.portal-section-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 1.5rem; flex-wrap: wrap; margin-bottom: 1.5rem; }
.portal-kicker { font: 500 0.72rem/1 var(--font); letter-spacing: .14em; text-transform: uppercase; color: var(--text-muted); margin-bottom: 6px; }
.portal-section-title { font-size: 1.75rem; font-weight: 700; letter-spacing: -.025em; color: var(--text); }
.portal-controls { display: flex; align-items: center; gap: 0.9rem; }
.portal-dots { display: flex; gap: 7px; }
.portal-dots button { width: 9px; height: 9px; padding: 0; border: none; border-radius: 50%; cursor: pointer; background: var(--border); }
.portal-dots button.active { background: var(--brand-blue); }
.btn-shuffle { font-family: var(--font); font-size: 0.8rem; font-weight: 500; color: var(--text-muted); background: var(--surface); border: 1px solid var(--border); padding: 8px 14px; border-radius: 8px; cursor: pointer; }
.btn-showall { font-family: var(--font); font-size: 0.8rem; font-weight: 500; color: var(--brand-blue); background: transparent; border: none; padding: 8px 2px; cursor: pointer; }

/* ── App shelf ──────────────────────────────────────── */
.app-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(206px, 1fr)); gap: 1rem; }
.app-card { display: flex; flex-direction: column; gap: 0.9rem; background: var(--surface); border: 1px solid var(--border); border-radius: 14px; padding: 14px; text-decoration: none; transition: transform .16s ease, box-shadow .16s ease, border-color .16s ease; }
.app-card:hover { transform: translateY(-3px); box-shadow: 0 12px 26px rgba(22,32,46,.09); border-color: var(--text-light); text-decoration: none; }
.app-card-icon { height: 76px; border-radius: 10px; display: flex; align-items: center; justify-content: center; }
.app-card-icon svg { width: 26px; height: 26px; }
.app-card-body { display: flex; flex-direction: column; gap: 5px; padding: 0 4px 6px; }
.app-card-name { font-size: 0.95rem; font-weight: 700; letter-spacing: -.01em; color: var(--text); line-height: 1.25; }
.app-card-sub { font-size: 0.8rem; line-height: 1.45; color: var(--text-muted); text-wrap: pretty; }

/* ── Games (deliberately dark regardless of theme — brand "night mode" island) ── */
.games-block { background: #16202E; border-radius: 16px; padding: 2rem; display: flex; flex-direction: column; gap: 1.4rem; }
.games-head { display: flex; align-items: center; gap: 12px; }
.games-head .portal-kicker { color: #8FA3BC; margin-bottom: 0; }
.games-head .rule { flex: 1; height: 1px; background: #2C3A4D; }
.games-head .aside { font-size: 0.8rem; color: #8FA3BC; }
.games-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); gap: 1rem; }
.game-card { display: flex; align-items: center; gap: 1.1rem; background: #1E2B3D; border: 1px solid #2C3A4D; border-radius: 13px; padding: 1.25rem; text-decoration: none; transition: background .16s ease; }
.game-card:hover { background: #25344A; text-decoration: none; }
.game-icon { width: 52px; height: 52px; border-radius: 16px; flex: 0 0 auto; position: relative; }
.game-icon span { position: absolute; inset: 0; margin: auto; width: 16px; height: 16px; border-radius: 50%; background: rgba(255,255,255,.9); animation: ecPulse 2.6s ease-in-out infinite; }
.game-name { font-size: 1.05rem; font-weight: 700; letter-spacing: -.015em; color: #fff; }
.game-sub { font-size: 0.8rem; line-height: 1.45; color: #8FA3BC; text-wrap: pretty; margin-top: 4px; }

/* ── Video index cards (videosto/index.html) ─────────────────────────
   Same tile language as .app-card on the main landing page, but the icon
   slot becomes a 16:9 poster. Cards are <a> elements straight to the page. */
.vidx-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(248px, 1fr)); gap: 1rem; }
.vidx-card { display: flex; flex-direction: column; gap: 0.75rem; background: var(--surface); border: 1px solid var(--border); border-radius: 14px; padding: 12px; text-decoration: none; transition: transform 180ms cubic-bezier(.2,.85,.3,1), box-shadow 180ms ease, border-color 180ms ease; }
.vidx-card:hover { transform: translateY(-3px); box-shadow: 0 12px 26px rgba(22,32,46,.09); border-color: var(--text-light); text-decoration: none; }
.vidx-poster { position: relative; aspect-ratio: 16 / 9; border-radius: 10px; overflow: hidden; background: #16202C center/cover no-repeat; }
.vidx-poster::after { content: ''; position: absolute; inset: 0; background: radial-gradient(ellipse at center, rgba(10,13,20,.14) 0%, rgba(10,13,20,.42) 100%); transition: background 200ms ease; }
.vidx-card:hover .vidx-poster::after { background: radial-gradient(ellipse at center, rgba(10,13,20,.05) 0%, rgba(10,13,20,.32) 100%); }
.vidx-play { position: absolute; inset: 0; margin: auto; width: 44px; height: 44px; z-index: 2; border-radius: 50%; background: rgba(16,19,26,.55); -webkit-backdrop-filter: blur(5px); backdrop-filter: blur(5px); border: 1.5px solid rgba(255,255,255,.38); display: flex; align-items: center; justify-content: center; transition: transform 200ms cubic-bezier(.2,.85,.3,1), background 200ms ease; }
.vidx-play svg { width: 17px; height: 17px; margin-left: 2px; fill: #fff; }
.vidx-card:hover .vidx-play { background: var(--primary); transform: scale(1.09); }
.vidx-badges { position: absolute; left: 7px; bottom: 7px; z-index: 2; display: flex; gap: 5px; }
.vidx-badge { font: 700 0.62rem/1 var(--font); letter-spacing: .05em; text-transform: uppercase; color: #fff; background: rgba(12,16,24,.72); -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px); padding: 4px 7px; border-radius: 6px; }
.vidx-body { display: flex; flex-direction: column; gap: 4px; padding: 0 3px 4px; }
.vidx-name { font-size: 0.92rem; font-weight: 700; letter-spacing: -.01em; color: var(--text); line-height: 1.28; }
.vidx-sub { font-size: 0.78rem; line-height: 1.45; color: var(--text-muted); text-wrap: pretty; }
.vidx-empty { padding: 2.5rem 2rem 3.5rem; text-align: center; color: var(--text-muted); font-size: 0.92rem; line-height: 1.7; }
.vidx-empty strong { color: var(--text); display: block; font-size: 1.05rem; margin-bottom: 0.35rem; }

/* ── Practice / video CTA cards ─────────────────────── */
.cta-grid { padding: 0 2rem 4rem; display: grid; grid-template-columns: 1.25fr 1fr; gap: 1rem; max-width: var(--portal-max); margin: 0 auto; box-sizing: border-box; }
.cta-card { display: flex; flex-direction: column; gap: 1.1rem; background: var(--surface); border: 1px solid var(--border); border-radius: 16px; padding: 1.75rem; text-decoration: none; }
.cta-card:hover { text-decoration: none; }
.cta-card-head { display: flex; align-items: baseline; justify-content: space-between; gap: 1rem; }
.cta-card-title { font-size: 1.35rem; font-weight: 700; letter-spacing: -.02em; color: var(--text); }
.cta-card-count { font: 500 0.72rem/1 var(--font); color: var(--brand-green); white-space: nowrap; }
.cta-card-body { font-size: 0.95rem; line-height: 1.55; color: var(--text-muted); text-wrap: pretty; }
.cta-chips { display: flex; flex-wrap: wrap; gap: 7px; }
.cta-chips span { font-size: 0.78rem; color: var(--text-muted); background: var(--bg); border: 1px solid var(--border); padding: 5px 10px; border-radius: 7px; }
.cta-card-link { font-size: 0.85rem; font-weight: 700; }
.cta-video-preview { height: 96px; border-radius: 11px; background: var(--brand-orange-tint); display: flex; align-items: flex-end; justify-content: center; gap: 6px; padding: 1rem; }
.cta-video-preview span { width: 12px; border-radius: 4px 4px 0 0; background: var(--brand-orange); animation: ecRise 2.8s ease-in-out infinite; }

/* ── Footer ─────────────────────────────────────────── */
.portal-footer { padding: 1.6rem 2rem; background: var(--surface); border-top: 1px solid var(--border); }
.portal-footer-inner { display: flex; align-items: center; justify-content: space-between; gap: 1.5rem; }
.portal-footer-inner p { font-size: 0.8rem; color: var(--text-muted); }
.footer-dots { display: flex; gap: 5px; }
.footer-dots span { width: 8px; height: 8px; border-radius: 50%; }

/* ── Skillsto: count badge, search, chip rail, topic groups ───────────── */
.sk-badge { font: 500 0.75rem/1 var(--font); color: var(--brand-green); background: var(--brand-green-tint); padding: 7px 11px; border-radius: 8px; white-space: nowrap; }
.sk-search-row { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; margin-top: 0.3rem; }
.sk-search { font-family: var(--font); font-size: 0.95rem; color: var(--text); background: var(--bg); border: 1px solid var(--border-strong); border-radius: 11px; padding: 0.8rem 1rem; width: 340px; max-width: 100%; outline: none; }
.sk-search:focus { border-color: var(--brand-green); background: var(--surface); }
.sk-clear-btn { font-family: var(--font); font-size: 0.85rem; font-weight: 500; color: var(--text-muted); background: var(--surface); border: 1px solid var(--border-strong); border-radius: 10px; padding: 0.8rem 1rem; cursor: pointer; }
.sk-result-label { font-size: 0.82rem; color: var(--text-light); }
.sk-chip-rail { background: var(--surface); border-bottom: 1px solid var(--border); position: sticky; top: 67px; z-index: 4; }
.sk-chip-rail-inner { max-width: var(--portal-max); margin: 0 auto; padding: 0.75rem 2rem; display: flex; flex-wrap: wrap; gap: 7px; box-sizing: border-box; }
.sk-chip { font-size: 0.78rem; font-weight: 500; color: var(--text-muted); background: var(--bg); border: 1px solid var(--border); padding: 6px 11px; border-radius: 8px; }
.sk-chip:hover { border-color: var(--brand-green); color: var(--brand-green); text-decoration: none; }
.sk-groups { flex: 1; max-width: var(--portal-max); width: 100%; margin: 0 auto; padding: 2.75rem 2rem 5rem; box-sizing: border-box; display: flex; flex-direction: column; gap: 2.75rem; }
.sk-group { display: flex; flex-direction: column; gap: 1rem; scroll-margin-top: 128px; }
.sk-group-head { display: flex; align-items: center; gap: 14px; }
.sk-group-dot { width: 10px; height: 10px; border-radius: 50%; }
.sk-group-name { font-size: 1.25rem; font-weight: 700; letter-spacing: -.02em; color: var(--text); }
.sk-group-rule { flex: 1; height: 1px; background: var(--border); }
.sk-group-count { font: 500 0.7rem/1 var(--font); color: var(--text-light); }
.sk-item-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 8px; }
.sk-item { display: flex; align-items: center; gap: 12px; background: var(--surface); border: 1px solid var(--border); border-radius: 10px; padding: 0.8rem 0.9rem; transition: border-color .14s ease, transform .14s ease; }
.sk-item:hover { border-color: var(--text-light); transform: translateX(2px); text-decoration: none; }
.sk-item-num { font: 500 0.7rem/1 var(--font); color: var(--text-light); width: 26px; flex: 0 0 auto; }
.sk-item-label { font-size: 0.9rem; line-height: 1.4; color: var(--text); text-wrap: pretty; }
.sk-empty { padding: 3.75rem 0; text-align: center; font-size: 1rem; color: var(--text-light); }

/* ── Video lesson page (per-classwork template) ─────────────────────── */
.vl-hero-inner { text-align: left; align-items: flex-start; gap: 0.6rem; padding: 2.25rem 2rem 1.5rem; }
.vl-back { font-size: 0.85rem; font-weight: 500; color: var(--text-muted); display: inline-flex; align-items: center; gap: 6px; margin-bottom: 0.3rem; }
.vl-back:hover { color: var(--brand-blue); text-decoration: none; }
.vl-title { font-size: 2rem; font-weight: 700; letter-spacing: -.025em; color: var(--text); }
.vl-count { font-size: 0.85rem; color: var(--text-light); }
.vl-list { max-width: 860px; margin: 0 auto; width: 100%; padding: 1.75rem 2rem 5rem; box-sizing: border-box; display: flex; flex-direction: column; gap: 2.5rem; }
.vl-problem { display: flex; flex-direction: column; gap: 0.75rem; scroll-margin-top: 84px; }
.vl-problem-title { font-size: 1rem; font-weight: 700; color: var(--text); line-height: 1.4; text-wrap: pretty; }
.vl-video { position: relative; width: 100%; aspect-ratio: 16 / 9; border-radius: 12px; overflow: hidden; background: #0b0f16; border: 1px solid var(--border); }
.vl-video-facade { position: absolute; inset: 0; width: 100%; height: 100%; border: none; padding: 0; cursor: pointer; background-size: cover; background-position: center; background-color: #16202E; }
.vl-play-btn { position: absolute; inset: 0; margin: auto; width: 64px; height: 64px; border-radius: 50%; background: rgba(16,19,26,.55); -webkit-backdrop-filter: blur(6px) saturate(1.15); backdrop-filter: blur(6px) saturate(1.15); border: 1.5px solid rgba(255,255,255,.38); box-shadow: 0 6px 22px rgba(0,0,0,.34); display: flex; align-items: center; justify-content: center; transition: transform 220ms cubic-bezier(.2,.85,.3,1), background 220ms ease, border-color 220ms ease; }
/* Scrim keeps the button legible on pale thumbnails and stops the frame
   looking washed out. Sits under the button, over the poster image. */
.vl-video-facade::after { content: ''; position: absolute; inset: 0; pointer-events: none; background: radial-gradient(ellipse at center, rgba(10,13,20,.20) 0%, rgba(10,13,20,.48) 100%); transition: background 220ms ease; }
.vl-video-facade:hover::after { background: radial-gradient(ellipse at center, rgba(10,13,20,.10) 0%, rgba(10,13,20,.40) 100%); }
/* Brand primary on hover rather than YouTube red — pure #FF0000 is the only
   saturated red anywhere in the platform and it reads as someone else's UI. */
.vl-video-facade:hover .vl-play-btn { background: var(--primary); border-color: rgba(255,255,255,.75); transform: scale(1.07); box-shadow: 0 10px 30px rgba(0,0,0,.42); }
.vl-video-facade:focus-visible { outline: 3px solid var(--primary); outline-offset: 3px; }
.vl-video-facade:active .vl-play-btn { transform: scale(1.01); }
.vl-play-btn svg { margin-left: 3px; }
.vl-video iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: none; }
.vl-no-video { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; color: #8FA3BC; font-size: 0.85rem; font-family: var(--font); text-align: center; padding: 1rem; }


/* ── Mobile nav drawer ──────────────────────────────────────────────────
   Below 720px the inline links are hidden, which previously left no way at
   all to reach the other subdomains on a phone in portrait. portal-nav.js
   clones whatever is already in .portal-nav-links into the drawer, so every
   page — including video lessons that do not exist yet — gets this for free
   with no per-page markup. Above 720px the inline links stay: a landing page
   earns visible wayfinding. */
.portal-burger { display: none; border: none; background: none; padding: 0; margin-right: 12px; cursor: pointer; color: var(--text-muted); align-items: center; }
.portal-burger svg { width: 1.35rem; height: 1.35rem; }
.portal-burger:hover { color: var(--primary); }
.portal-drawer { position: fixed; inset: 0; z-index: 200; visibility: hidden; opacity: 0; transition: opacity 200ms ease, visibility 200ms; }
.portal-drawer[data-open="true"] { visibility: visible; opacity: 1; }
.portal-drawer-scrim { position: absolute; inset: 0; background: var(--overlay, rgba(17,24,39,.45)); }
.portal-drawer-panel { position: absolute; top: 0; left: 0; bottom: 0; width: min(78vw, 300px); background: var(--surface); border-right: 1px solid var(--border); box-shadow: 0 0 40px rgba(0,0,0,.18); padding: 1.1rem 1.1rem 2rem; display: flex; flex-direction: column; gap: 0.15rem; transform: translateX(-102%); transition: transform 240ms cubic-bezier(.2,.85,.3,1); }
.portal-drawer[data-open="true"] .portal-drawer-panel { transform: none; }
.portal-drawer-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 0.6rem; }
.portal-drawer-title { font-size: 1.05rem; letter-spacing: -.03em; color: var(--text); line-height: 1; }
.portal-drawer-title .light { font-weight: 400; }
.portal-drawer-title .bold { font-weight: 700; }
.portal-drawer-close { border: none; background: none; padding: 4px; cursor: pointer; color: var(--text-muted); display: flex; }
.portal-drawer-close svg { width: 1.15rem; height: 1.15rem; }
.portal-drawer-panel a { display: block; padding: 0.68rem 0.6rem; border-radius: 9px; font-size: 0.95rem; font-weight: 500; color: var(--text); text-decoration: none; }
.portal-drawer-panel a:hover { background: var(--primary-light); color: var(--primary); text-decoration: none; }
@media (max-width: 720px) { .portal-burger { display: inline-flex; } }

@media (max-width: 720px) {
  .portal-nav-links { display: none; }
  .portal-headline { font-size: 2.4rem; }
  .portal-tagline { font-size: 1.1rem; }
  .cta-grid { grid-template-columns: 1fr; }
}
