/* ==========================================================================
   Studio Selhes — stylesheet
   Quiet, text-first, single narrow column. Geist for text, Geist Mono for
   small meta (numbers, years, labels, time). Grey body text, small
   medium-weight headings, one tiny accent.
   1. Font  2. Tokens + dark mode  3. Base  4. Layout  5. Components
   6. Motion  7. Case study template
   ========================================================================== */

/* 1. Fonts (self-hosted, SIL OFL, Latin subset — no third-party requests) */
@font-face { font-family: "Geist"; src: url("../fonts/geist-400.woff2?v=54333601") format("woff2"); font-weight: 400; font-style: normal; font-display: swap; }
@font-face { font-family: "Geist"; src: url("../fonts/geist-500.woff2?v=3f6fb8fe") format("woff2"); font-weight: 500; font-style: normal; font-display: swap; }
@font-face { font-family: "Geist Mono"; src: url("../fonts/geist-mono-400.woff2?v=62de638c") format("woff2"); font-weight: 400; font-style: normal; font-display: swap; }
/* Metric-matched fallback (Arial/Arimo scaled to Geist's width and ascent), so the swap to Geist doesn't reflow the hero. */
@font-face { font-family: "Geist Fallback"; src: local("Arial"), local("ArialMT"), local("Arimo"); size-adjust: 105.5%; ascent-override: 95.2%; descent-override: 27.9%; line-gap-override: 0%; }

/* 2. Tokens --------------------------------------------------------------- */
:root {
  color-scheme: light;
  --bg:     #fbfbfa;
  --text:   #1b1b19;   /* headings, names, links       16.6:1 */
  --muted:  #6a6964;   /* body / descriptions           5.4:1 */
  --faint:  #e4e3de;   /* hairlines                           */
  --line:   #c9c8c2;   /* resting link underline              */
  --accent: #d2421f;   /* status dot + text selection tint    */
  --ring:   rgb(255 255 255 / 0.14);  /* inset ring on the dark button */

  --font: "Geist", "Geist Fallback", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --mono: "Geist Mono", ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  --fs-xs:   0.75rem;    /* 12px  mono meta           */
  --fs-sm:   0.8125rem;  /* 13px  footer, small notes */
  --fs-base: 0.9375rem;  /* 15px  everything else    */
  --lh:      1.65;

  --space-1: 4px;  --space-2: 8px;  --space-3: 12px; --space-4: 16px;
  --space-5: 24px; --space-6: 32px; --space-7: 48px; --space-8: 64px;
  --section-gap: 64px;
  --column: 36rem;      /* 576px text column */

  /* Motion language: one curve, a small duration scale.
     Only transform and opacity are ever animated. */
  --ease-out:    cubic-bezier(0.23, 1, 0.32, 1);
  --dur-press:   150ms;   /* :active feedback               */
  --dur-ui:      200ms;   /* hover nudges, toggle icon swaps */
  --dur-enter:   300ms;   /* reveal, per element             */
  --stagger:     45ms;
  --dur-reveal: 640ms;  --stagger-block: 70ms;  --blur: 6px;
  --press-scale: 0.97;    /* icon buttons etc.               */
  --mark:        2.8125rem; /* 45px: two lines at 15px × 1.5  */
  --r-pill: 9999px;  --r-box: 8px;  --r-sm: 4px;   /* radius language */
  --hover-scale: 1.04;    /* pill fill on hover (animations.dev feel) */
  --pill-press:  0.97;    /* pill fill on press              */
  --dur-tap:     150ms;   /* press-in                        */
  --rise:        7px;     /* reveal travel                   */
  --dur-ambient: 2400ms;  /* slow loops: status pulse         */
}
/* Dark tokens: system preference, unless the visitor picked light via the
   toggle; or forced with data-theme="dark". Both blocks are identical. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;
    --bg: #111110; --text: #ecebe7; --muted: #9d9c96; --faint: #262523; --line: #464541; --accent: #f0643f;
    --ring: rgb(0 0 0 / 0.12);
  }
}
:root[data-theme="dark"] {
  color-scheme: dark;
  --bg: #111110; --text: #ecebe7; --muted: #9d9c96; --faint: #262523; --line: #464541; --accent: #f0643f;
  --ring: rgb(0 0 0 / 0.12);
}

/* 3. Base ----------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
body {
  margin: 0;
  background: var(--bg);
  color: var(--muted);
  font: 400 var(--fs-base)/var(--lh) var(--font);
  letter-spacing: -0.003em;
  font-feature-settings: "kern", "liga";
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
h1, h2, h3 { margin: 0; font-size: inherit; font-weight: 500; color: var(--text); letter-spacing: -0.01em; }
p { margin: 0 0 1em; text-wrap: pretty; }
p:last-child { margin-bottom: 0; }
ul, ol { margin: 0; padding: 0; list-style: none; }
strong { font-weight: 500; color: var(--text); }
img, svg { display: block; max-width: 100%; height: auto; }
::selection { background: color-mix(in srgb, var(--accent) 22%, transparent); color: var(--text); }

a {
  color: var(--text);
  text-decoration: underline;
  text-decoration-color: var(--line);
  text-decoration-thickness: 1px;
  text-underline-offset: 0.24em;
  text-decoration-skip-ink: auto;
}
a:hover { text-decoration-color: currentColor; }

:focus-visible { outline: 1.5px solid var(--text); outline-offset: 3px; border-radius: var(--r-sm); }
.btn:focus-visible { border-radius: var(--r-pill); }

.skip-link {
  position: absolute; left: var(--space-4); top: -100px; z-index: 10;
  padding: var(--space-2) var(--space-3); background: var(--text); color: var(--bg);
  border-radius: var(--r-pill); text-decoration: none;
}
.skip-link:focus { top: var(--space-4); }
.visually-hidden {
  position: absolute !important; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.mono, .rows .when, .clock {
  font-family: var(--mono); font-size: var(--fs-xs); letter-spacing: 0;
  font-variant-numeric: tabular-nums;
}

/* 4. Layout --------------------------------------------------------------- */
.page {
  max-width: calc(var(--column) + 48px);
  margin: 0 auto;
  padding: clamp(56px, 12vh, 112px) 24px 48px;
}
section { margin-top: var(--section-gap); }
section > h2 { margin-bottom: var(--space-4); }
/* One rhythm in every section: heading → text → list. */
section > p + ul, section > p + ol { margin-top: var(--space-5); }

/* 5. Components ----------------------------------------------------------- */

/* Header: name + role, quiet icon toggles on the right. */
.intro-head { display: flex; justify-content: space-between; align-items: flex-start; gap: var(--space-4); }
.intro-head h1, .intro-head .brand { margin: 0; line-height: 1.45; font-weight: 500; color: var(--text); }
.intro-head .brand a { color: inherit; text-decoration: none; }
.intro-head .role { margin: 0; line-height: 1.45; text-wrap: balance; }
.toggles { display: flex; gap: 2px; margin: -2px -6px 0 0; }

.icon-btn {
  position: relative; display: grid; place-items: center; width: 28px; height: 28px; padding: 0;
  background: none; border: 0; border-radius: var(--r-pill); color: var(--muted); cursor: pointer;
  transition: transform var(--dur-press) var(--ease-out);
}
/* Soft hover disc: a pseudo-element that fades + scales in. */
.icon-btn::before {
  content: ""; position: absolute; inset: 0; border-radius: inherit;
  background: color-mix(in srgb, var(--text) 7%, transparent);
  opacity: 0; transform: scale(0.8);
  transition: opacity var(--dur-ui) var(--ease-out), transform var(--dur-ui) var(--ease-out);
}
@media (hover: hover) and (pointer: fine) {
  .icon-btn:hover { color: var(--text); }
  .icon-btn:hover::before { opacity: 1; transform: none; }
}
.icon-btn:active { transform: scale(0.92); }
.icon-btn svg { position: relative; width: 15px; height: 15px; grid-area: 1 / 1; }
.no-js .toggles { display: none; }

/* Theme icon: moon ⇄ sun cross-fade with a small turn. */
.theme-toggle .i-sun, .theme-toggle .i-moon {
  transition: opacity var(--dur-ui) var(--ease-out), transform var(--dur-enter) var(--ease-out);
}
.theme-toggle .i-sun { opacity: 0; transform: rotate(-90deg) scale(0.5); }
:root[data-theme="dark"] .theme-toggle .i-sun { opacity: 1; transform: none; }
:root[data-theme="dark"] .theme-toggle .i-moon { opacity: 0; transform: rotate(90deg) scale(0.5); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .theme-toggle .i-sun { opacity: 1; transform: none; }
  :root:not([data-theme="light"]) .theme-toggle .i-moon { opacity: 0; transform: rotate(90deg) scale(0.5); }
}

/* Sound icon: four small bars that "play" while sound is on and settle
   flat when off. Spans (not SVG) so the scale animation is composited. */
.sound-toggle .bars { position: relative; display: flex; align-items: center; gap: 2px; height: 12px; }
.sound-toggle .bars span {
  display: block; width: 2px; height: 12px; border-radius: 1px; background: currentColor;
  transform: scaleY(0.17);
  transition: transform var(--dur-enter) var(--ease-out);
}
.sound-toggle[aria-pressed="true"] .bars span { transform: scaleY(0.55); }
.sound-toggle[aria-pressed="true"] .bars span:nth-child(2) { transform: scaleY(0.9); }
.sound-toggle[aria-pressed="true"] .bars span:nth-child(3) { transform: scaleY(0.7); }
@media (prefers-reduced-motion: no-preference) {
  .sound-toggle[aria-pressed="true"] .bars span { animation: eq 1100ms var(--ease-out) infinite alternate; }
  .sound-toggle[aria-pressed="true"] .bars span:nth-child(2) { animation-duration: 800ms;  animation-delay: -300ms; }
  .sound-toggle[aria-pressed="true"] .bars span:nth-child(3) { animation-duration: 1300ms; animation-delay: -650ms; }
  .sound-toggle[aria-pressed="true"] .bars span:nth-child(4) { animation-duration: 950ms;  animation-delay: -150ms; }
  @keyframes eq { from { transform: scaleY(0.25); } to { transform: scaleY(1); } }
}

/* Tooltip: one shared element (main.js), centred on its trigger. Small
   container, hairline + soft shadow; scales in from the trigger side.
   Mouse (after 300ms; instantly when moving between tooltips) and
   keyboard focus only — never on touch. Esc hides it. */
.tip {
  position: fixed; left: 0; top: 0; z-index: 50; pointer-events: none;
  display: flex; align-items: center; gap: 6px; padding: 4px 8px; white-space: nowrap;
  font-size: var(--fs-xs); line-height: 16px; color: var(--text); letter-spacing: 0.005em;
  background: var(--bg); border-radius: var(--r-box);
  box-shadow: 0 0 0 1px var(--faint), 0 4px 12px -2px rgb(0 0 0 / 0.10), 0 1px 2px rgb(0 0 0 / 0.06);
  opacity: 0; transform: scale(0.97);
  transition: opacity var(--dur-press) var(--ease-out), transform var(--dur-press) var(--ease-out);
}
.tip.is-on { opacity: 1; transform: none; }
.tip.is-instant { transition: none; }
:root[data-theme="dark"] .tip { background: #1b1a19; box-shadow: 0 0 0 1px var(--line), 0 6px 16px -2px rgb(0 0 0 / 0.5); }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .tip { background: #1b1a19; box-shadow: 0 0 0 1px var(--line), 0 6px 16px -2px rgb(0 0 0 / 0.5); } }
kbd {
  font-family: var(--mono); font-size: 10px; line-height: 1; color: var(--muted);
  padding: 2px 4px 3px; border-radius: var(--r-sm);
  box-shadow: inset 0 0 0 1px var(--line);
}

/* Theme switch: a quick cross-fade of the whole page (View Transitions,
   opacity only); falls back to an instant swap. */
::view-transition-old(root), ::view-transition-new(root) {
  animation-duration: var(--dur-enter); animation-timing-function: var(--ease-out);
}
/* Theme reveal (theme-fx.js): the new theme is uncovered by a clip that
   grows from the toggle; the WebGL canvas (own transition group) draws the
   noisy, grainy edge on top so the text underneath stays crisp. */
.vt-reveal::view-transition-old(root), .vt-reveal::view-transition-new(root) { animation: none; mix-blend-mode: normal; }
.vt-reveal::view-transition-old(fx) { display: none; }
.vt-reveal::view-transition-new(fx) { animation: none; }
.vt-reveal::view-transition-group(fx) { animation: none; z-index: 2; }
.fx-canvas { position: fixed; inset: 0; width: 100vw; height: 100vh; z-index: 100; pointer-events: none; view-transition-name: fx; }

.lede { margin-top: var(--space-7); }
.lede .positioning { color: var(--text); }

/* Dot sits on the first line, so a wrapped status (narrow screens) still reads cleanly. */
/* flex-basis (not the text) decides whether the status sits beside the button, so filling in the month never moves it. */
.status { display: flex; flex: 1 1 22.5rem; align-items: flex-start; gap: 10px; margin: 0; line-height: 1.5; text-wrap: balance; }
.status::before {
  content: ""; flex: none; margin-top: calc((1.5em - 6px) / 2); width: 6px; height: 6px; border-radius: 50%; background: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 18%, transparent);
}
/* Gentle pulse: a ring that grows and fades (static with reduced motion). */
.status { position: relative; }
.status::after {
  content: ""; position: absolute; left: 0; top: calc((1.5em - 6px) / 2); width: 6px; height: 6px; border-radius: 50%;
  background: var(--accent); opacity: 0; pointer-events: none;
}
@media (prefers-reduced-motion: no-preference) {
  .status::after { animation: pulse var(--dur-ambient) var(--ease-out) infinite; }
  @keyframes pulse { 0% { opacity: 0.45; transform: scale(1); } 60%, 100% { opacity: 0; transform: scale(3.2); } }
}

/* Narrow screens: the status wraps to two lines once the date is filled in; reserve them so nothing below shifts. */
@media (max-width: 27rem) { .status { min-height: 3em; } }
.actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-3) var(--space-5); margin-top: var(--space-5); }

/* Pill button (.btn): the fill/ring lives on ::before and only that layer
   scales — up a little on hover, down on press. The label and the button
   box never change size, so nothing shifts. */
.btn { position: relative; isolation: isolate; }
.btn::before {
  content: ""; position: absolute; inset: 0; z-index: -1; border-radius: inherit;
  /* The one deliberate exception to transform/opacity: a small fill-colour
     shift that pairs with the scale (as on animations.dev). */
  transition: transform var(--dur-ui) var(--ease-out), background-color var(--dur-ui) var(--ease-out);
}
@media (hover: hover) and (pointer: fine) {
  .btn:hover::before { transform: scale(var(--hover-scale)); background-color: color-mix(in srgb, var(--text) 88%, var(--bg)); }
}
.btn:active::before { transform: scale(var(--pill-press)); transition-duration: var(--dur-tap); }

/* Primary button: dark pill with a 1px inset ring. */
.btn {
  display: inline-block; padding: 6px 15px; border-radius: var(--r-pill);
  color: var(--bg); text-decoration: none; font-weight: 500;
}
.btn::before {
  background-color: var(--text);
  box-shadow: inset 0 0 0 1px var(--ring), inset 0 1px 0 rgb(255 255 255 / 0.10), 0 1px 2px rgb(0 0 0 / 0.10);
}

/* Arrow: ↗ only on links that open another site in a new tab. */
.arrow-link { white-space: nowrap; }
.arrow {
  display: inline-block; margin-left: 0.2em; color: var(--muted); text-decoration: none;
  font-size: 0.9em; transition: transform var(--dur-ui) var(--ease-out);
}
@media (hover: hover) and (pointer: fine) {
  .arrow-link:hover .arrow { transform: translate(2px, -2px); color: var(--text); }
}

/* Items (Services + Process): one structure. A square "mark" the height of
   the two-line row (icon or number centred), then name + grey description.
   Static on purpose: no hover effects. */
.items li { display: grid; grid-template-columns: var(--mark) 1fr; column-gap: var(--space-4); align-items: start; }
.items li + li { margin-top: var(--space-4); }
.mark {
  display: grid; place-items: center; width: var(--mark); height: var(--mark);
  border-radius: var(--r-box); color: var(--muted);
  background: color-mix(in srgb, var(--text) 2.5%, transparent);
  box-shadow: inset 0 0 0 1px var(--faint);
}
.mark svg { width: 18px; height: 18px; }
.mark--num { font-family: var(--mono); font-size: var(--fs-xs); font-variant-numeric: tabular-nums; letter-spacing: 0; }
.items .body { display: flex; flex-direction: column; justify-content: center; min-height: var(--mark); }
.items .name { color: var(--text); line-height: 1.5; }
.items .desc { line-height: 1.5; }

/* Rows (About, Tools, Contact): one structure with hairline dividers.
   Left: name (+ optional logo, grey description). Right: value — a date
   (mono) or a link. */
.rows { position: relative; border-top: 1px solid var(--faint); }
.rows li {
  display: flex; justify-content: space-between; align-items: baseline; gap: var(--space-4);
  padding: 8px 0; line-height: 1.5; border-bottom: 1px solid var(--faint);
}
.rows .k { display: flex; align-items: baseline; flex-wrap: wrap; column-gap: 0.5em; color: var(--text); min-width: 0; }
.rows .k .desc { color: var(--muted); }
.rows .kt { display: flex; flex-wrap: wrap; align-items: baseline; column-gap: 0.5em; min-width: 0; }
/* Narrow screens: every role sits on its own line under the name (same in each row). */
@media (max-width: 30rem) { .rows .kt .desc { flex-basis: 100%; } }
.rows .v { position: relative; text-align: right; white-space: nowrap; }
.rows .when { color: var(--muted); }
.logo {
  flex: none; align-self: flex-start; margin-top: calc((1.5em - 16px) / 2); width: 16px; height: 16px; border-radius: var(--r-sm); margin-right: 0.15em;
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--text) 10%, transparent);
}

/* Cursor-aware highlight: one soft block that glides between rows
   (transform + opacity only; positioned by main.js; fine pointers). */
.row-hl {
  position: absolute; left: -10px; right: -10px; top: 0; z-index: -1; pointer-events: none;
  border-radius: var(--r-box); background: color-mix(in srgb, var(--text) 4.5%, transparent);
  opacity: 0;
  transition: opacity var(--dur-ui) var(--ease-out), transform var(--dur-ui) var(--ease-out);
}
.row-hl.is-on { opacity: 1; }
.row-hl.no-slide { transition: opacity var(--dur-ui) var(--ease-out); }
.page { position: relative; z-index: 0; }
/* While a row is highlighted, its own dividers (above and below) fade out,
   so the highlight never stacks with hairlines. */
.rows, .rows li { transition: border-color var(--dur-ui) var(--ease-out); }
@media (hover: hover) and (pointer: fine) {
  .rows li:hover,
  .rows li:has(+ li:hover) { border-bottom-color: transparent; }
  .rows:has(> li:first-of-type:hover) { border-top-color: transparent; }
}

/* Copy email: a small icon button in the gutter LEFT of the address
   (absolutely positioned, so nothing shifts). Mouse: shows on row hover.
   Keyboard: shows on focus. Touch: always visible. Copy icon morphs into a
   check for a moment after copying. */
.copy {
  position: absolute; right: calc(100% + 6px); top: 50%; translate: 0 -50%;
  display: grid; place-items: center; width: 22px; height: 22px; padding: 0;
  background: none; border: 0; border-radius: var(--r-sm); color: var(--muted); cursor: pointer;
  opacity: 0;
  transition: opacity var(--dur-ui) var(--ease-out), transform var(--dur-press) var(--ease-out);
}
.copy[hidden] { display: none; }
.copy svg { grid-area: 1 / 1; width: 13px; height: 13px; transition: opacity var(--dur-ui) var(--ease-out), transform var(--dur-ui) var(--ease-out); }
.copy .i-check { opacity: 0; transform: scale(0.5); }
.copy.is-done .i-copy { opacity: 0; transform: scale(0.5); }
.copy.is-done .i-check { opacity: 1; transform: none; color: var(--text); }
.copy:active { transform: scale(0.9); }
.rows li:hover .copy, .copy:focus-visible, .copy.is-done, .rows li:focus-within .copy { opacity: 1; }
@media (hover: hover) and (pointer: fine) { .copy:hover { color: var(--text); } }
@media (hover: none), (pointer: coarse) { .copy { opacity: 1; } }

/* Anagram: a single word at body size; letters swap once (FLIP in JS). */
.anagram { display: inline-flex; color: var(--text); }
.anagram span { display: inline-block; }

/* Placeholders — visible while drafting; quiet but unmistakable. */
.ph {
  color: var(--muted);
  font-size: 0.92em;
  border-bottom: 1px dashed var(--muted);
  white-space: nowrap;
}

footer {
  display: flex; flex-wrap: wrap; justify-content: space-between; gap: var(--space-2) var(--space-4);
  margin-top: var(--section-gap); padding-top: var(--space-5);
  border-top: 1px solid var(--faint);
  font-size: var(--fs-sm); letter-spacing: 0.005em;
}
footer p { margin: 0; }
.foot-meta p + p { margin-top: 2px; }
.clock { align-self: flex-end; }
.clock time { color: var(--text); }
@media (prefers-reduced-motion: no-preference) {
  .clock .colon { animation: blink 1000ms var(--ease-out) infinite alternate; }
  @keyframes blink { from { opacity: 1; } to { opacity: 0.2; } }
}

/* 6. Motion ----------------------------------------------------------------
   - Reveal: [data-reveal] blocks fade/rise in once as they enter the
     viewport (IntersectionObserver in main.js adds .is-in); children are
     staggered via --i. Hidden state only applies with JS + motion allowed,
     and the header is never hidden, so first paint/LCP register at once.
   - .fade: plain CSS load reveal for the small 404/template pages.        */
@media (prefers-reduced-motion: no-preference) {
  /* Entrance: opacity + 7px rise + 6px blur → sharp, 640ms, strong ease-out.
     Blocks stagger in reading order on load (--b, 70ms); items inside a
     block follow at 45ms (--i). The blur is a short-lived exception to
     "transform/opacity only" and is removed once settled (.is-done). */
  .js [data-reveal] .r { opacity: 0; transform: translateY(var(--rise)); filter: blur(var(--blur)); }
  .js [data-reveal].is-in .r {
    opacity: 1; transform: none; filter: none;
    transition: opacity var(--dur-reveal) var(--ease-out), transform var(--dur-reveal) var(--ease-out), filter var(--dur-reveal) var(--ease-out);
    transition-delay: calc(var(--b, 0) * var(--stagger-block) + var(--i, 0) * var(--stagger));
  }
  .js [data-reveal].is-done .r { transition: none; filter: none; }
  .fade { animation: fade-in var(--dur-enter) var(--ease-out) both; animation-delay: calc(var(--d, 0) * 50ms); }
  @keyframes fade-in { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
}
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
  /* Pills: no scaling, just a colour change. */
  .btn:hover::before, .btn:active::before { transform: none; }
  .btn:hover::before { background-color: color-mix(in srgb, var(--text) 86%, var(--bg)); }
}

/* 7. Case study template (/work/*.html) ------------------------------------ */
.template-note {
  font-size: var(--fs-sm); padding: var(--space-3) var(--space-4); margin-bottom: var(--space-7);
  border: 1px dashed var(--muted); border-radius: var(--r-box);
}
.back { display: inline-block; margin-bottom: var(--space-7); }
.meta { margin-top: var(--space-5); }
.meta div { display: flex; justify-content: space-between; gap: var(--space-4); line-height: 1.5; }
.meta div + div { margin-top: var(--space-2); }
.meta dt { color: var(--muted); }
.meta dd { margin: 0; color: var(--text); text-align: right; }
.media { margin: var(--space-6) 0 0; }
.media .frame {
  aspect-ratio: 16 / 10; border-radius: var(--r-box); background: color-mix(in srgb, var(--text) 4%, var(--bg));
  display: grid; place-items: center; font-size: var(--fs-sm); overflow: hidden;
}
.media .frame img, .media .frame video { width: 100%; height: 100%; object-fit: cover; }
.media figcaption { font-size: var(--fs-sm); margin-top: var(--space-2); }
/* Optional: let a visual break out of the column on wide screens. */
@media (min-width: 900px) { .media--wide { margin-inline: -96px; } }

