/* ─────────────────────────────────────────
   DESIGN SYSTEM
───────────────────────────────────────── */
:root {
  /* ── DARK MODE ─────────────────────────────
     Midnight  #121212   bg
     Ivory     #F8F6EE   text
     Lavender  #ACA0E8   primary — links, CTAs, reading marker
     Lilac     #8E7FD1   accent  — highlights, decorative (primary-family shade)
  ─────────────────────────────────────────── */
  --color-bg:               #121212;   /* base — never pure #000 */
  --color-surface:          #1E1D1A;   /* elevated: a step LIGHTER than bg, warm */
  --color-surface-2:        #26241F;   /* second elevation */
  --color-border:           rgba(248, 246, 238, 0.10);   /* hairline defines dark cards */

  --color-text:             #F8F6EE;
  --color-text-muted:       rgba(248, 246, 238, 0.60);
  --color-text-subtle:      rgba(248, 246, 238, 0.20);

  --color-primary:          #ACA0E8;
  --color-primary-muted:    rgba(172, 160, 232, 0.12);

  --color-accent:           #8E7FD1;
  --color-accent-on-accent: #121212;

  /* Theme-swapped — see .btn below. On hover .btn fills solid
     --color-primary; this is the foreground that sits on that fill.
     Dark mode's primary (lavender) is light, so this is dark; light
     mode overrides it below because its primary (cobalt) is dark and
     needs a light foreground instead — plain dark text there fails
     contrast (~2.5:1). */
  --color-on-primary:       #121212;

  --highlight-ink:          172, 160, 232;  /* highlighter marker RGB (lilac) */

  /* Typography */
  --font-display: 'Manrope', sans-serif;
  --font-body:    'Manrope', sans-serif;
  --font-mono:    'Manrope', sans-serif;

  /* Type scale — matched to Pencil design system */
  --text-2xs:  0.5625rem;  /* 9px  — Label Small */
  --text-xs:   0.6875rem;  /* 11px — Label */
  --text-sm:   0.875rem;   /* 14px — Body Small / Caption */
  --text-base: 1rem;       /* 16px — Body */
  --text-lg:   1.75rem;    /* 28px — H4 */
  --text-2xl:  2.75rem;    /* 44px — H3 */
  --text-3xl:  4.3125rem;  /* 69px — H2 */
  --text-4xl:  5.5rem;     /* 88px — H1 */

  /* Leading */
  --leading-tight:    1.1;    /* H1, H2 */
  --leading-snug:     1.18;   /* H3 */
  --leading-normal:   1.4;    /* H4, Body caption */
  --leading-body:     1.6;    /* Body */
  --leading-loose:    1.8;    /* Body bold */
  --leading-medium:   1.5;    /* Body small */

  /* Tracking */
  --tracking-tight:   -0.04em; /* H1 */
  --tracking-snug:    -0.02em; /* H2 */
  --tracking-normal:   0em;
  --tracking-wide:     0.04em;
  --tracking-wider:    0.1em;  /* Label */
  --tracking-widest:   0.16em; /* Label Small */

  /* Space */
  --sp-1:  0.25rem;
  --sp-2:  0.5rem;
  --sp-3:  0.75rem;
  --sp-4:  1rem;
  --sp-5:  1.25rem;
  --sp-6:  1.5rem;
  --sp-8:  2rem;
  --sp-10: 2.5rem;
  --sp-12: 3rem;
  --sp-16: 4rem;
  --sp-20: 5rem;
  --sp-24: 6rem;

  /* Layout */
  --left-col: 400px;
  --panel-transition: 420ms ease;
  --nav-height: 3.25rem;

  /* ── COMPONENT: Link 1 — Panel CTA (.panel-cta) ──────────────────
     Text + filled circle arrow. Used in right-column panels below image.
     Font:    --font-display, --text-sm (14px), weight 500
     Colour:  --color-text default → --color-primary on hover
     Circle:  36×36px, border-radius 50%, background --color-primary
              white SVG arrow; rotates 45° on hover
     Spacing: margin-top --sp-10 above component
  ─────────────────────────────────────────────────────────────────── */
}

/* ── LIGHT MODE ────────────────────────────
     Peach cream  #FFF3E8   bg
     Navy         #1A2A5E   text
     Cobalt       #2147CC   primary — links, CTAs, reading marker
     Periwinkle   #5B6FD6   accent  — highlights, decorative (primary-family shade)
  ─────────────────────────────────────────── */
[data-theme="light"] {
  --color-bg:               #FFF3E8;
  --color-surface:          #FFE0C4;
  --color-surface-2:        #FFD0A8;
  --color-border:           rgba(26, 42, 94, 0.10);

  --color-text:             #1A2A5E;
  --color-text-muted:       rgba(26, 42, 94, 0.68);
  --color-text-subtle:      rgba(26, 42, 94, 0.20);

  --color-primary:          #2147CC;
  --color-primary-muted:    rgba(33, 71, 204, 0.11);

  --color-accent:           #5B6FD6;
  --color-accent-on-accent: #FFF3E8;

  /* Cobalt primary is dark — needs a light foreground on hover fills,
     the opposite of dark mode's lavender. Warm ivory, not pure white,
     matching the "no pure black/white" principle. */
  --color-on-primary:       #F8F6EE;

  --highlight-ink:          33, 71, 204;  /* highlighter marker RGB (cobalt) */
}

/* ── COMPONENT: Button — Text (.btn) ────────────────────────
   The one text-button treatment used everywhere on the site (pill
   badges, form actions, resume downloads). Rest is a quiet outline —
   it doesn't compete with primary content. Hover fills solid
   --color-primary (swaps with theme: cobalt in light, lavender in
   dark) with --color-on-primary — also theme-swapped, so the fill
   always gets a contrast-safe foreground instead of one fixed value.
   Sizes: --xs (pill badges, 11px) · --sm (compact, 14px) ·
   --md (standard form actions, 14px, more padding).
──────────────────────────────────────────────────────────── */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5em;
  border: 1px solid var(--color-border);
  border-radius: 999px;
  background: var(--color-surface);
  color: var(--color-text);
  font-family: var(--font-mono);
  font-weight: 600;   /* design.md Font Weight Usage: 600 — "bold accents within body" */
  text-transform: uppercase;
  text-decoration: none;
  cursor: pointer;
  transition: color 200ms ease, border-color 200ms ease, background 200ms ease;
}
.btn:hover {
  background: var(--color-primary);
  border-color: var(--color-primary);
  color: var(--color-on-primary);
}
.btn .material-symbols-rounded { font-size: 18px; }

/* Email copy tooltip — shown via components/tooltip.js, which adds
   .b-tt-anchor (dotted underline + help cursor). A button shouldn't
   read as a text link, so strip that affordance and keep pointer. */
.btn[data-tooltip] { position: relative; }
button[data-copy].b-tt-anchor {
  display: inline-flex;
  align-items: center;
  text-decoration: none;
  cursor: pointer;
}
/* During the "Copied!" feedback the tooltip is redundant — hide the pill
   (and its hover affordance) so it never re-opens while feedback shows. */
.btn.is-copied .b-tt { display: none; }
.btn.is-copied.b-tt-anchor,
.btn.is-copied.b-tt-anchor:hover,
.btn.is-copied.b-tt-anchor:focus-visible {
  text-decoration-color: transparent;
}

.btn--xs {
  padding: 2px 10px;
  font-size: var(--text-xs);
  letter-spacing: var(--tracking-widest);
  line-height: 1.15;
}
.btn--sm {
  padding: 4px var(--sp-6);
  font-size: var(--text-sm);
  letter-spacing: var(--tracking-wider);
}
.btn--md {
  padding: var(--sp-3) var(--sp-6);
  font-size: var(--text-sm);
  letter-spacing: var(--tracking-wider);
}

/* ─────────────────────────────────────────
   RESET & BASE
───────────────────────────────────────── */
::selection { background: var(--color-primary); color: var(--color-accent-on-accent); }

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

html {
  font-size: 16px;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

body {
  background: var(--color-bg);
  color: var(--color-text);
  font-family: var(--font-body);
  font-size: var(--text-base);
  font-weight: 400;
  line-height: var(--leading-normal);
  min-height: 100vh;
}

a {
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
  text-decoration-color: var(--color-border);
  transition: color 120ms ease, text-decoration-color 120ms ease;
}
a:hover {
  color: var(--color-primary);
  text-decoration-color: var(--color-primary);
}

/* ─────────────────────────────────────────
   PAGE LAYOUT — two-column grid
───────────────────────────────────────── */
.page {
  display: grid;
  grid-template-columns: var(--left-col) 1fr;
  min-height: 100vh;
}

/* Left: normal scroll column */
.page-left {
  border-right: 1px solid var(--color-border);
  position: relative;
  z-index: 1;
}

/* Right: empty grid column — fixed panels overlay this space */
.page-right { /* intentionally empty */ }

/* ─────────────────────────────────────────
   SITE NAV  (full-width sticky top bar)
───────────────────────────────────────── */
.site-nav {
  position: sticky;
  top: 0;
  z-index: 20;
  background: var(--color-bg);
  border-bottom: 1px solid var(--color-border);
  padding: var(--sp-4) var(--sp-8);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-4);
  /* full width — outside the two-column grid */
  width: 100%;
}

.nav-name {
  font-family: var(--font-display);
  font-size: var(--text-sm);
  font-weight: 600;
  letter-spacing: var(--tracking-tight);
  text-decoration: none;
  white-space: nowrap;
  color: var(--color-text);
}
.nav-name:hover { color: var(--color-primary); text-decoration: none; }

.nav-resume-icon {
  font-size: 1em;
  vertical-align: -0.15em;
  line-height: 1;
}

.nav-resume-group {
  display: flex;
  align-items: center;
  gap: 0.25em;
}

.nav-resume-label {
  font-family: var(--font-display);
  font-size: var(--text-sm);
  font-weight: 600;
  letter-spacing: var(--tracking-tight);
  color: var(--color-text);
  cursor: default;
}

.nav-resume-link {
  cursor: pointer;
  text-decoration: none;
  transition: color 120ms ease;
}
.nav-resume-link:hover { color: var(--color-primary); }

.nav-links {
  display: flex;
  gap: var(--sp-4);
  list-style: none;
}

.nav-links a {
  font-family: var(--font-mono);
  font-size: var(--text-2xs);
  letter-spacing: var(--tracking-wider);
  text-transform: uppercase;
  text-decoration: none;
  color: var(--color-text-muted);
  white-space: nowrap;
  transition: color 120ms ease;
}
.nav-links a:hover { color: var(--color-text); }

/* ─────────────────────────────────────────
   READING MARKER
───────────────────────────────────────── */
.reading-marker {
  position: fixed;
  left: 3px;
  top: 33.33vh;
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: var(--color-primary);
  opacity: 0.35;
  z-index: 100;
  pointer-events: none;
}

/* ─────────────────────────────────────────
   TEXT BLOCKS  (left column content)
───────────────────────────────────────── */
.block-text {
  padding: var(--sp-16) var(--sp-8);
  border-bottom: 1px solid var(--color-border);
  position: relative;
  min-height: calc(100vh - var(--nav-height));
  display: flex;
  flex-direction: column;
  justify-content: center;
}

.block-text:last-of-type {
  padding-bottom: var(--sp-24);
  border-bottom: none;
}

/* Label — mono, small, muted */
.b-label {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-weight: 500;
  letter-spacing: var(--tracking-widest);
  text-transform: uppercase;
  color: var(--color-text-muted);
  margin-bottom: var(--sp-5);
}
/* Color variant — same type, full-strength text instead of muted.
   Compose onto .b-label: class="b-label b-label-strong". */
.b-label-strong { color: var(--color-text); }

/* Title */
.b-title {
  font-family: var(--font-display);
  font-size: var(--text-2xl);
  font-weight: 700;
  letter-spacing: 0;
  line-height: var(--leading-snug);
  margin-bottom: var(--sp-5);
}

.b-title--xl {
  font-size: var(--text-4xl);
  letter-spacing: var(--tracking-tight);
  line-height: var(--leading-tight);
  margin-bottom: var(--sp-4);
}

/* Article title — responsive hero for long-form case studies (two-column) */
.b-title--article {
  font-family: var(--font-display);
  font-size: clamp(2.25rem, 4.5vw, 3.25rem);
  font-weight: 700;
  letter-spacing: var(--tracking-snug);
  line-height: var(--leading-tight);
  margin-bottom: 0;
}

/* Section header — long-form section heading (28px) */
.b-section-header {
  font-family: var(--font-display);
  font-size: var(--text-lg);
  font-weight: 700;
  line-height: var(--leading-normal);
  letter-spacing: 0;
  color: var(--color-text);
  margin-bottom: var(--sp-6);
}

/* Section subheader — sub-heading within a section (16px) */
.b-section-subheader {
  font-family: var(--font-display);
  font-size: var(--text-base);
  font-weight: 600;
  letter-spacing: 0;
  line-height: var(--leading-body);
  margin-top: var(--sp-10);
  margin-bottom: var(--sp-3);
}

/* Body */
.b-body {
  font-size: var(--text-base);
  line-height: var(--leading-body);
  max-width: 62ch;   /* readable measure — long-form line length cap */
}
.b-body + .b-body { margin-top: var(--sp-4); }

/* Body bold */
.b-body-bold {
  font-size: var(--text-base);
  font-weight: 600;
  line-height: var(--leading-loose);
}

/* Body image caption */
.b-body-caption {
  font-size: var(--text-sm);
  font-weight: 500;
  line-height: var(--leading-normal);
}

/* Body small — regular */
.b-body-small {
  font-size: var(--text-sm);
  font-weight: 400;
  line-height: var(--leading-medium);
}

/* Body small — bold */
.b-body-small-impact {
  font-size: var(--text-sm);
  font-weight: 700;
  line-height: var(--leading-medium);
}

/* Link */
.b-link {
  display: inline-block;
  margin-top: var(--sp-6);
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: var(--tracking-wide);
  color: var(--color-primary);
  text-decoration: none;
}
.b-link:hover { text-decoration: underline; text-decoration-color: var(--color-primary); color: var(--color-primary); }

/* Label link — quiet uppercase navigational/utility link (back links, TOC, in-page nav).
   Reads as a label, not prose. Muted by default, primary on hover. */
.b-label-link {
  font-size: var(--text-xs);
  font-weight: 500;
  letter-spacing: var(--tracking-wider);
  text-transform: uppercase;
  color: var(--color-text-muted);
  text-decoration: none;
  transition: color 120ms ease;
}
.b-label-link:hover { color: var(--color-primary); }

/* Email copy — left col */
.email-copy-wrap {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
}

.email-copy-pill {
  display: inline-block;
  font-family: var(--font-display);
  font-size: var(--text-sm);
  font-weight: 600;
  letter-spacing: var(--tracking-tight);
  color: var(--color-text);
  background: none;
  border: 1px solid var(--color-border);
  border-radius: 2px;
  padding: var(--sp-3) var(--sp-5);
  cursor: pointer;
  transition: background 200ms ease, border-color 200ms ease, color 200ms ease;
}
.email-copy-pill:hover {
  background: var(--color-primary-muted);
  border-color: var(--color-primary);
  color: var(--color-primary);
}

.email-copy-hint {
  font-size: var(--text-sm);
  color: var(--color-text-muted);
  margin-top: var(--sp-2);
}

/* Email copy — right panel */
.p-email.email-copy-pill {
  cursor: pointer;
}

.p-copy-hint {
  font-family: var(--font-mono);
  font-size: var(--text-2xs);
  letter-spacing: var(--tracking-wider);
  text-transform: uppercase;
  color: rgba(255,255,255,0.35);
  margin-top: var(--sp-2);
}

/* Timeline (inside left col) */
.b-timeline {
  margin-top: var(--sp-8);
  display: flex;
  flex-direction: column;
  gap: var(--sp-5);
}
.b-timeline-item {
  display: grid;
  grid-template-columns: 5.5rem 1fr;
  gap: var(--sp-3);
}
.b-timeline-period {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: var(--color-text-muted);
  letter-spacing: var(--tracking-wide);
  padding-top: 0.1rem;
}
.b-timeline-role { font-size: var(--text-sm); font-weight: 400; }
.b-timeline-company {
  font-family: var(--font-mono);
  font-size: var(--text-2xs);
  color: var(--color-text-muted);
  letter-spacing: var(--tracking-wide);
  margin-top: var(--sp-1);
}

/* Skills grid (inside left col) */
.b-skills {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--sp-5) var(--sp-8);
  margin-top: var(--sp-8);
}
.b-skill-name { font-size: var(--text-sm); font-weight: 400; }
.b-skill-desc {
  font-family: var(--font-mono);
  font-size: var(--text-2xs);
  color: var(--color-text-muted);
  letter-spacing: var(--tracking-wide);
  margin-top: var(--sp-1);
}

/* Footer */
.site-footer {
  padding: var(--sp-10) var(--sp-8);
  border-top: 1px solid var(--color-border);
}
.site-footer-copy {
  font-family: var(--font-mono);
  font-size: var(--text-2xs);
  color: var(--color-text-muted);
  letter-spacing: var(--tracking-wide);
}

/* ─────────────────────────────────────────
   FIXED PANELS  (right column overlay)
───────────────────────────────────────── */
.panel {
  position: fixed;
  top: var(--nav-height);
  left: var(--left-col);
  right: 0;
  bottom: 0;
  display: none;            /* hidden until in-view */
  flex-direction: column;
  justify-content: center;
  align-items: center;
  padding: var(--sp-8);
  opacity: 0;
  transition: opacity var(--panel-transition);
  z-index: 1;
  overflow: hidden;
}

/* Panel enters viewport — display: flex, but still invisible */
.block-text.in-view + .panel {
  display: flex;
}

/* Panel crosses reading line — fade in */
.block-text.active + .panel {
  display: flex;
  opacity: 1;
  z-index: 2;
}

/* ── PANEL INTERNALS ── */

.p-inner {
  width: 100%;
  max-width: 560px;
  text-align: center;
}

.p-inner--left { text-align: left; }

.p-label {
  font-family: var(--font-mono);
  font-size: var(--text-2xs);
  letter-spacing: var(--tracking-widest);
  text-transform: uppercase;
  opacity: 0.45;
  margin-bottom: var(--sp-6);
}

.p-display {
  font-family: var(--font-display);
  font-size: clamp(2.75rem, 7vw, 6rem);
  font-weight: 700;
  letter-spacing: var(--tracking-tight);
  line-height: var(--leading-tight);
}

.p-sub {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: var(--tracking-wider);
  text-transform: uppercase;
  opacity: 0.45;
  margin-top: var(--sp-6);
}

.p-divider {
  width: 100%;
  max-width: 320px;
  height: 1px;
  background: currentColor;
  opacity: 0.12;
  margin: var(--sp-8) auto 0;
}

/* ── PANEL THEMES ── */

/* 1 — Intro */
.panel--intro { background: #000; }

.p-stats {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--sp-4);
  margin-top: var(--sp-10);
  padding-top: var(--sp-8);
  border-top: 1px solid var(--color-border);
}
.p-stat-val {
  font-family: var(--font-display);
  font-size: var(--text-3xl);
  font-weight: 700;
  letter-spacing: var(--tracking-tight);
  line-height: 1;
}
.p-stat-lbl {
  font-family: var(--font-mono);
  font-size: var(--text-2xs);
  letter-spacing: var(--tracking-wider);
  text-transform: uppercase;
  color: var(--color-text-muted);
  margin-top: var(--sp-2);
}

/* 2 — Bounce: image panel */
.panel--bounce { background: #000; }

/* 3 — Unbabel: image panel */
.panel--unbabel { background: #000; }

/* 4 — Decision Module: image panel */
.panel--decision { background: #000; }

.panel-img {
  max-width: 88%;
  width: auto;
  height: auto;
  max-height: 85%;
  object-fit: contain;
  object-position: center top;
  display: block;
  border-radius: 4px;
  box-shadow: 0 16px 48px rgba(0, 0, 0, 0.28);
  flex-shrink: 0;
}

/* ── FRAME CYCLE (crossfading thumbnail) ── */
.frame-cycle {
  position: relative;
  width: 88%;
  max-width: 900px;
  aspect-ratio: 4964 / 3394;
  max-height: 85%;
  flex-shrink: 0;
  overflow: hidden;
  border-radius: 4px;
  container-type: size;
}
.frame-cycle img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  border-radius: 0;
  box-shadow: none;
  z-index: 1;
  opacity: 0;
}
/* Frame 1 is the default poster before JS takes over the sequence. */
.frame-cycle img:nth-child(2) { opacity: 1; }

/* Giant cancellation-rate number that counts down behind each frame.
   Rendered with screen blend so it reads as a dark figure on the black
   areas of the frame, but disappears wherever the white phone sits on top. */
.frame-nums {
  /* Hidden for now — the story is told by cutting through the four
     iteration frames rather than by an overlaid number. */
  display: none;
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  mix-blend-mode: screen;
}
.frame-num {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 118cqh;
  line-height: 1;
  font-weight: 700;
  letter-spacing: -0.04em;
  color: #2a2a2a;
  font-variant-numeric: tabular-nums;
}

/* The frame sequence and number countdown are both driven from JS
   (see startFrameSequence in main.js), starting once frames have loaded. */

@media (prefers-reduced-motion: reduce) {
  /* Static poster: frame 1 + starting number, handled by the default
     opacity above and by main.js settling the number on its start value. */
}

/* Mobile-only CTA — hidden on desktop, shown inside .block-text on mobile */
.mobile-cta { display: none; }

/* Hidden for now — "View project" CTA in the right-hand panel column */
.panel .panel-cta { display: none; }

/* Panel CTA — sits below the image, centred in the panel */
.panel-cta {
  margin-top: var(--sp-10);
  display: inline-flex;
  align-items: center;
  gap: var(--sp-4);
  font-family: var(--font-display);
  font-size: var(--text-sm);
  font-weight: 500;
  letter-spacing: 0;
  text-transform: none;
  color: var(--color-text);
  text-decoration: none;
  flex-shrink: 0;
  transition: color 150ms ease;
}
.panel-cta:hover {
  color: var(--color-primary);
  text-decoration: none;
}
.panel-cta-circle {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: var(--color-primary);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  transition: transform 200ms ease;
}
.panel-cta:hover .panel-cta-circle {
  transform: rotate(45deg);
}

/* Back variant — circle on left, arrow points left, rotates +45° on hover
   so the arrow angles upward (up-left) rather than down. */
.panel-cta--back .panel-cta-circle {
  order: -1;
}
.panel-cta--back:hover .panel-cta-circle {
  transform: rotate(45deg);
}
.panel-cta-circle svg {
  width: 14px;
  height: 14px;
  stroke: #fff;
  fill: none;
  stroke-width: 1.75;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.panel-img-caption {
  position: absolute;
  bottom: var(--sp-6);
  left: var(--sp-8);
  right: var(--sp-8);
  font-family: var(--font-mono);
  font-size: var(--text-2xs);
  letter-spacing: var(--tracking-wider);
  text-transform: uppercase;
  color: rgba(255,255,255,0.5);
  z-index: 2;
}

.panel-img-caption--dark {
  color: rgba(0,0,0,0.35);
}

.p-relation {
  display: flex;
  align-items: center;
  gap: var(--sp-6);
  justify-content: center;
  margin-top: var(--sp-10);
}
.p-relation-node {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: var(--tracking-wider);
  text-transform: uppercase;
  color: var(--color-text-muted);
  border: 1px solid var(--color-border);
  border-radius: 2px;
  padding: var(--sp-2) var(--sp-4);
}
.p-relation-arrow {
  font-size: var(--text-lg);
  color: var(--color-primary);
  font-weight: 300;
}

/* ── B-META — case study metadata fields in left sidebar ── */
.b-meta {
  display: flex;
  flex-direction: column;
  gap: var(--sp-5);
  list-style: none;
  margin-top: var(--sp-8);
}

.b-meta-item {
  display: flex;
  flex-direction: column;
  gap: var(--sp-1);
}

.b-meta-label {
  font-family: var(--font-mono);
  font-size: var(--text-2xs);
  letter-spacing: var(--tracking-widest);
  text-transform: uppercase;
  color: var(--color-text-muted);
}

.b-meta-value {
  font-size: var(--text-sm);
  font-weight: 500;
  line-height: var(--leading-normal);
}

/* 5 — TRQ DAD: image panel */
.panel--trq { background: #000; }

/* 6 — Cocoon: warm tint */
.panel--cocoon { background: var(--color-accent); }

/* 7 — Experience */
.panel--experience { background: #000; }

.p-timeline {
  width: 100%;
  max-width: 460px;
  margin-top: var(--sp-8);
}
.p-tl-item {
  display: grid;
  grid-template-columns: 5.5rem 1fr;
  gap: var(--sp-4);
  padding: var(--sp-4) 0;
  border-bottom: 1px solid var(--color-border);
}
.p-tl-item:first-child { border-top: 1px solid var(--color-border); }
.p-tl-period {
  font-family: var(--font-mono);
  font-size: var(--text-2xs);
  color: var(--color-text-muted);
  letter-spacing: var(--tracking-wide);
  padding-top: 0.1rem;
}
.p-tl-role { font-size: var(--text-sm); font-weight: 400; }
.p-tl-company {
  font-family: var(--font-mono);
  font-size: var(--text-2xs);
  color: var(--color-text-muted);
  letter-spacing: var(--tracking-wide);
  margin-top: var(--sp-1);
}

/* 8 — Skills/About: dark */
.panel--skills { background: var(--color-text); color: var(--color-bg); }

.p-skills {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--sp-5) var(--sp-10);
  margin-top: var(--sp-8);
  text-align: left;
  width: 100%;
  max-width: 400px;
}
.p-skill-name { font-size: var(--text-sm); font-weight: 400; }
.p-skill-desc {
  font-family: var(--font-mono);
  font-size: var(--text-2xs);
  letter-spacing: var(--tracking-wide);
  opacity: 0.45;
  margin-top: var(--sp-1);
}

/* 9 — Contact: accent red */
.panel--contact { background: var(--color-primary); color: var(--color-accent-on-accent); }

.p-email {
  display: inline-block;
  font-family: var(--font-display);
  font-size: clamp(0.9rem, 2vw, 1.35rem);
  font-weight: 600;
  letter-spacing: var(--tracking-tight);
  color: inherit;
  text-decoration: none;
  margin-top: var(--sp-8);
  padding: var(--sp-4) var(--sp-6);
  border: 1px solid rgba(255, 255, 255, 0.4);
  border-radius: 2px;
  transition: background 200ms ease;
}
.p-email:hover { background: rgba(255,255,255,0.15); color: #fff; text-decoration: none; }

.p-contact-links {
  display: flex;
  gap: var(--sp-6);
  margin-top: var(--sp-5);
}
.p-contact-links a {
  font-family: var(--font-mono);
  font-size: var(--text-2xs);
  letter-spacing: var(--tracking-wider);
  text-transform: uppercase;
  color: rgba(255,255,255,0.55);
  text-decoration: none;
  transition: color 150ms ease;
}
.p-contact-links a:hover { color: #fff; }

/* ─────────────────────────────────────────
   MOBILE HERO  (shown only on mobile)
───────────────────────────────────────── */
.mobile-hero {
  display: none; /* hidden on desktop */
}

/* ─────────────────────────────────────────
   MOBILE VISUAL  (inline card on mobile,
   hidden on desktop — replaces fixed panel)
───────────────────────────────────────── */
.mobile-visual {
  display: none; /* hidden on desktop */
}

/* ─────────────────────────────────────────
   TABLET  (512px – 768px)
───────────────────────────────────────── */
@media (min-width: 32rem) and (max-width: 768px) {
  .page-left {
    border-right: none;
  }

  .block-text {
    padding: var(--sp-16) 12.5vw;
    min-height: unset;
    display: block;
  }

  .block-text:last-of-type {
    padding-bottom: var(--sp-20);
    border-bottom: none;
  }

  .mobile-hero {
    padding: var(--sp-16) 12.5vw var(--sp-12);
  }

  .mobile-visual {
    padding: var(--sp-10) 12.5vw;
  }

  .site-footer {
    padding: var(--sp-8) 12.5vw;
  }
}

/* ─────────────────────────────────────────
   TYPE SCALE BREAKPOINTS
───────────────────────────────────────── */

/* Medium — 1200 to 1440px */
@media (max-width: 1440px) {
  :root {
    /* H1: 88px — same as Large */
    --text-3xl: 3.25rem;   /* 52px — H2 */
    --text-2xl: 2.375rem;  /* 38px — H3 */
    /* H4: 28px — same as Large */
  }
}

/* Small — 810 to 1200px */
@media (max-width: 1200px) {
  :root {
    --text-4xl: 4.5rem;    /* 72px — H1 */
    --text-3xl: 2.5rem;    /* 40px — H2 */
    --text-2xl: 2.125rem;  /* 34px — H3 */
    --text-lg:  1.5rem;    /* 24px — H4 */
  }
}

/* X-Small — ≤810px */
@media (max-width: 810px) {
  :root {
    --text-4xl: 2.875rem;  /* 46px — H1 */
    --text-3xl: 2.5rem;    /* 40px — H2 */
    --text-2xl: 1.625rem;  /* 26px — H3 */
    --text-lg:  1.375rem;  /* 22px — H4 */
    --text-sm:  0.75rem;   /* 12px — Body Small */
  }
}

/* ─────────────────────────────────────────
   WIDE DESKTOP  (>= 1280px)
   Left col grows 400→600px, reaches 600 at 1600px
───────────────────────────────────────── */
@media (min-width: 1280px) {
  :root {
    --left-col: clamp(400px, 62.5vw - 400px, 600px);
  }
}


/* ─────────────────────────────────────────
   MOBILE  (<= 768px)
───────────────────────────────────────── */
@media (max-width: 768px) {
  .page {
    display: block;
  }

  /* Hide all fixed panels on mobile */
  .panel {
    display: none !important;
  }

  /* Show in-block CTA links on mobile */
  .mobile-cta {
    display: inline-flex;
  }

  /* Show inline mobile visuals */
  .mobile-visual {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 52vw;
    padding: var(--sp-10) var(--sp-6);
    border-bottom: 1px solid var(--color-border);
    text-align: center;
  }

  .mobile-visual--dark { background: var(--color-text); color: var(--color-bg); }
  .mobile-visual--red  { background: var(--color-primary); color: var(--color-accent-on-accent); }
  .mobile-visual--soft { background: var(--color-primary); }
  .mobile-visual--plain { background: var(--color-bg); }

  .mv-inner { width: 100%; }

  .mv-label {
    font-family: var(--font-mono);
    font-size: var(--text-2xs);
    letter-spacing: var(--tracking-widest);
    text-transform: uppercase;
    opacity: 0.45;
    margin-bottom: var(--sp-4);
  }

  .mv-title {
    font-family: var(--font-display);
    font-size: var(--text-3xl);
    font-weight: 700;
    letter-spacing: var(--tracking-tight);
    line-height: var(--leading-tight);
  }

  .mv-sub {
    font-family: var(--font-mono);
    font-size: var(--text-2xs);
    letter-spacing: var(--tracking-wider);
    text-transform: uppercase;
    opacity: 0.45;
    margin-top: var(--sp-4);
  }

  /* Image mobile-visual */
  .mobile-visual--img {
    background: #000;
    padding: var(--sp-8);
    min-height: 60vw;
    display: flex;
    align-items: center;
    justify-content: center;
    position: relative;
    overflow: hidden;
  }

  .mobile-visual--img img {
    width: 88%;
    height: auto;
    max-height: 85%;
    object-fit: contain;
    border-radius: 4px;
    box-shadow: 0 12px 32px rgba(0, 0, 0, 0.28);
    object-position: center top;
    display: block;
  }

  /* Hide the desktop intro block — mobile-hero replaces it */
  .block-text--intro {
    display: none;
  }

  /* Show mobile hero */
  .mobile-hero {
    display: block;
    padding: var(--sp-16) var(--sp-6) var(--sp-12);
    border-bottom: 1px solid var(--color-border);
  }

  .reading-marker { display: none; }

  .page-right { display: none; }

  /* Nav: hide links on small screens, keep name + section count.
     On mobile the .site-nav bar picks up --color-surface so it reads
     as a soft, distinct step above the darker --color-bg — matches
     the .btn / .tile surface token, no new variable. */
  .nav-links { display: none; }

  .site-nav {
    padding: var(--sp-4) var(--sp-6);
    background: var(--color-surface);
  }

  /* Reduce block vertical rhythm */
  .block-text {
    padding: var(--sp-12) var(--sp-6);
    min-height: unset;
    display: block;
  }

  .block-text:last-of-type {
    padding-bottom: var(--sp-16);
    border-bottom: none;
  }

  .site-footer {
    padding: var(--sp-8) var(--sp-6);
  }

  /* Stack timeline labels above content on very small screens */
  .b-timeline-item {
    grid-template-columns: 4.5rem 1fr;
    gap: var(--sp-2);
  }
}

/* ─────────────────────────────────────────
   SMALL MOBILE  (<= 400px)
───────────────────────────────────────── */
@media (max-width: 400px) {
  .block-text {
    padding: var(--sp-10) var(--sp-5);
  }
}

/* ─────────────────────────────────────────
   TIMEZONE COMPONENT
───────────────────────────────────────── */
.b-tz {
  position: relative;
  display: inline-flex;
  align-self: flex-start;
  align-items: center;
  gap: var(--sp-2);
  font-size: var(--text-sm);
  color: var(--color-text);
  border: 1px solid var(--color-border);
  border-radius: 999px;
  padding: var(--sp-2) var(--sp-4);
  margin-top: var(--sp-5);
  line-height: 1;
  cursor: default;
}
.b-tz-icon {
  font-size: 16px;
  line-height: 1;
  color: var(--color-text);
  font-variation-settings: 'FILL' 1, 'wght' 400, 'GRAD' 0, 'opsz' 20;
}
.b-tz::after {
  content: 'Lisbon, Portugal';
  position: absolute;
  bottom: calc(100% + var(--sp-2));
  left: 50%;
  transform: translateX(-50%) translateY(4px);
  background: var(--color-surface-2);
  border: 1px solid var(--color-border);
  border-radius: var(--sp-2);
  padding: var(--sp-1) var(--sp-3);
  font-size: var(--text-xs);
  color: var(--color-text-muted);
  white-space: nowrap;
  pointer-events: none;
  opacity: 0;
  transition: opacity 150ms ease, transform 150ms ease;
}
.b-tz:hover::after {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}

/* ─────────────────────────────────────────
   ANIMATION
───────────────────────────────────────── */
@keyframes fade-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}
body {
  animation: fade-in 250ms ease;
  transition: background 300ms ease, color 300ms ease;
}

/* ─────────────────────────────────────────
   HOME ⇄ CASE-STUDY TRANSITION — two-column rail hand-off
   Native cross-document View Transitions. Every page is two columns — a left
   "index" column (home nav rail ⇄ case-study TOC rail) and a right "content"
   column — and each animates ON ITS OWN. Nothing morphs into anything else:
   there are no shared view-transition-names, so the browser never tries to
   interpolate one page's element into a differently-shaped one (that warp/pop
   was why the earlier image-morph and eyebrow-morph attempts read as janky).

   Choreography (asymmetric):
     Home → case-study:
       1. the home left rail flies out to the left,
       2. the home right column dissolves to blank (staggered behind the rail),
       3. the entire case-study page (both rail + content) slides in from the top.
     Case-study → home:
       1. the case-study left rail flies out to the left,
       2. the case-study right column zooms out (scale + fade), revealing
          the homepage right column underneath,
       3. the homepage left rail zooms in, flying in from the left.

   Pure CSS — no JS orchestration. The one supporting change lives in
   components/case-study.js: it builds .cs-rail synchronously so the incoming
   rail exists in first paint and can be captured here.

   The ::view-transition-* pseudo-elements are styled by the DESTINATION
   document, so these rules must live in style.css (the only stylesheet both
   page types load). Browsers without cross-document view transitions ignore
   the at-rule and navigate plainly; reduced-motion opts out explicitly.
───────────────────────────────────────── */
@view-transition { navigation: auto; }
@media (prefers-reduced-motion: reduce) {
  @view-transition { navigation: none; }
}

/* Names — static, one per page. Each appears in only one document, so on any
   navigation the browser sees each as old-only (exits) or new-only (enters). */
#rail        { view-transition-name: rail-home; }
main.content { view-transition-name: col-home; }
.cs-rail     { view-transition-name: rail-cs; }
.cs-content  { view-transition-name: col-cs; }

/* OLD — left rail flies out to the left (both directions). */
::view-transition-old(rail-home),
::view-transition-old(rail-cs) {
  animation: rail-out 300ms cubic-bezier(0.65, 0, 0.35, 1) both;
}
@keyframes rail-out { to { transform: translateX(-120%); opacity: 0; } }

/* OLD — case-study content slides up (case-study → home). Reverse of page-in. */
::view-transition-old(col-cs) {
  animation: slide-up 400ms cubic-bezier(0.65, 0, 0.35, 1) both;
}
@keyframes slide-up { to { transform: translateY(-60px); opacity: 0; } }

/* OLD — home content dissolves to blank (home → case-study). */
::view-transition-old(col-home) {
  animation: col-out 200ms cubic-bezier(0.65, 0, 0.35, 1) 50ms both;
}
@keyframes col-out { to { opacity: 0; } }

/* NEW — case-study rail + content slide in from top (home → case-study).
       250ms delay so the old home content has fully faded before the new
       content appears. */
::view-transition-new(rail-cs),
::view-transition-new(col-cs) {
  animation: page-in 400ms cubic-bezier(0.65, 0, 0.35, 1) 250ms both;
}
@keyframes page-in {
  from { transform: translateY(-60px); opacity: 0; }
}

/* NEW — home left rail slides in from the left (case-study → home).
       Ease-out curve (fast start, decelerating settle) so the rail
       feels responsive when returning home — the eye tracks the entry
       then relaxes as it lands. Other transitions use a symmetrical
       ease-in-out because they pair an exit and an entrance on different
       elements; the rail has no paired exit (it already left), so a
       bouncy ease-in-out would feel sluggish here. */
::view-transition-new(rail-home) {
  animation: rail-in 400ms cubic-bezier(0.16, 1, 0.3, 1) 100ms both;
}
@keyframes rail-in {
  from { transform: translateX(-120%); opacity: 0; }
}

/* NEW — home content fades in after the CS content has cleared. */
::view-transition-new(col-home) {
  animation: home-in 250ms cubic-bezier(0.65, 0, 0.35, 1) 200ms both;
}
@keyframes home-in {
  from { opacity: 0; }
}

/* Everything unnamed (page background, theme toggle, progress bar) is captured
   as `root`. A short cross-fade — the background tokens match across pages, so
   this is effectively invisible and just avoids a hard cut. */
::view-transition-old(root),
::view-transition-new(root) {
  animation-duration: 250ms;
  animation-timing-function: cubic-bezier(0.65, 0, 0.35, 1);
}

/* The floating light/dark toggle button (.theme-btn) and its
   styles live in components/theme.js so they inject on every page. */
