/* =========================================================================
   Félix POS — Portfolio 2026
   Design tokens. Change these values to re-skin the entire site.
   ========================================================================= */

:root {
  color-scheme: light;

  /* --- Colour ------------------------------------------------------------
     Cream paper + near-black ink + one electric blue.
     Swap --accent alone to change the whole site's personality.
     Every colour below is redefined for dark mode further down; nothing
     here is hard-coded into a component. */
  --paper:        #F1F0EB;
  --paper-deep:   #E7E5DE;
  --ink:          #111111;
  --ink-2:        #4A4843;
  --ink-3:        #6E6B64;   /* AA-safe at 10-12px mono: 4.66:1 on paper */
  --rule:         #D6D3CA;
  --rule-soft:    #E2DFD7;

  --accent:       #2B34E8;   /* filled surfaces (contact band, hover fills) */
  --accent-text:  #2B34E8;   /* accent used as text or a hairline on paper  */
  --ember:        #F0522B;

  /* Inverted panels: the ticker, "areas of opportunity" and the footer. */
  --invert-bg:    #121211;
  --invert-fg:    #F1F0EB;
  --invert-fg-2:  #9C9A93;
  --invert-rule:  #2C2B28;

  /* Accent sitting on an inverted panel. Deliberately the same in both
     themes: the panel is dark either way, so one bright blue serves both. */
  --accent-inv:   #7B83FF;

  /* --- Type -------------------------------------------------------------- */
  --sans: "Archivo", "Helvetica Neue", Helvetica, Arial, sans-serif;
  --mono: "Geist Mono", ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;

  /* --- Metrics ----------------------------------------------------------- */
  --nav-h: 68px;             /* nav bar height, used by the hero's fold maths */
  --ticker-h: 58px;          /* credentials band height (max 57px), ditto */
  --shell: 1560px;
  --gutter: clamp(20px, 4.2vw, 64px);
  --band: clamp(72px, 9vw, 148px);   /* vertical section rhythm */
  --hair: 1px;
  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
}

/* Dark mode is declared twice on purpose:
   - the media query covers viewers on the default "system" setting, guarded
     so an explicit light choice still wins over a dark OS;
   - the [data-theme] rule covers an explicit choice from the toggle.
   Keep the two blocks identical. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;
  /* Page */
  --paper:        #111110;
  --paper-deep:   #1A1917;
  --ink:          #F2F1EC;
  --ink-2:        #A5A29A;
  --ink-3:        #8A877F;
  --rule:         #302E2A;
  --rule-soft:    #232220;

  /* Accent: a surface blue lifted off the ground, and a lighter text blue.
     One value cannot do both jobs on a dark ground — white on a blue bright
     enough to read as text would itself fail. */
  --accent:       #3B45F0;
  --accent-text:  #7B83FF;
  --ember:        #FF6A44;

  /* Inverted panels stay darker than the page rather than flipping bright,
     so scrolling through dark mode never flashes. */
  --invert-bg:    #1C1B18;
  --invert-fg:    #F2F1EC;
  --invert-fg-2:  #9C9A93;
  --invert-rule:  #34322D;
  }
}

:root[data-theme="dark"] {
  color-scheme: dark;
  /* Page */
  --paper:        #111110;
  --paper-deep:   #1A1917;
  --ink:          #F2F1EC;
  --ink-2:        #A5A29A;
  --ink-3:        #8A877F;
  --rule:         #302E2A;
  --rule-soft:    #232220;

  /* Accent: a surface blue lifted off the ground, and a lighter text blue.
     One value cannot do both jobs on a dark ground — white on a blue bright
     enough to read as text would itself fail. */
  --accent:       #3B45F0;
  --accent-text:  #7B83FF;
  --ember:        #FF6A44;

  /* Inverted panels stay darker than the page rather than flipping bright,
     so scrolling through dark mode never flashes. */
  --invert-bg:    #1C1B18;
  --invert-fg:    #F2F1EC;
  --invert-fg-2:  #9C9A93;
  --invert-rule:  #34322D;
}

/* =========================================================================
   Reset / base
   ========================================================================= */

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: 96px;
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--sans);
  font-size: clamp(15px, 1.02vw, 17px);
  line-height: 1.6;
  font-weight: 400;
  letter-spacing: -0.006em;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  font-synthesis-weight: none;
  overflow-x: hidden;
}

h1, h2, h3, h4 { margin: 0; font-weight: 600; letter-spacing: -0.035em; line-height: 0.98; }
p  { margin: 0; }
ul, ol { margin: 0; padding: 0; list-style: none; }
img, svg { display: block; max-width: 100%; }
a  { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; border: 0; background: none; cursor: pointer; }

::selection { background: var(--accent); color: #fff; }

:focus-visible {
  outline: 2px solid var(--accent-text);
  outline-offset: 3px;
  border-radius: 1px;
}

.skip {
  position: absolute; left: -9999px; top: 0; z-index: 999;
  background: var(--ink); color: var(--paper);
  padding: 14px 20px; font-family: var(--mono); font-size: 12px;
}
.skip:focus { left: 12px; top: 12px; }

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* =========================================================================
   Layout primitives
   ========================================================================= */

.shell {
  width: 100%;
  max-width: var(--shell);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.band { padding-block: var(--band); }
.band--tight { padding-block: clamp(48px, 5.5vw, 92px); }

.rule-top { border-top: var(--hair) solid var(--rule); }

/* Section header: mono index label + title, split across the grid */
/* Eyebrow label stacked above the title, both starting at the page margin.
   The label previously sat in a 20% column, which squeezed longer ones onto
   two lines and broke the bracket off on its own. */
.sec-head {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: clamp(16px, 1.6vw, 24px);
  margin-bottom: clamp(40px, 4.6vw, 76px);
}

.sec-title {
  font-size: clamp(2rem, 4.4vw, 3.9rem);
  max-width: 20ch;
  text-wrap: balance;
}

/* =========================================================================
   Mono label — the connective tissue of the whole site
   ========================================================================= */

.label {
  font-family: var(--mono);
  font-size: clamp(10px, 0.72vw, 11.5px);
  font-weight: 400;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-3);
  line-height: 1.4;
}
.label--ink   { color: var(--ink); }
.label--blue  { color: var(--accent-text); }
.label--dark  { color: var(--invert-fg-2); }

/* Bracketed variant: [ ABOUT ] */
.label--bracket::before { content: "[ "; }
.label--bracket::after  { content: " ]"; }

/* Slash variant: /Contact */
.label--slash::before { content: "/"; }

/* =========================================================================
   Nav
   ========================================================================= */

.nav {
  position: sticky;
  top: 0;
  z-index: 100;
  background: color-mix(in srgb, var(--paper) 88%, transparent);
  backdrop-filter: saturate(180%) blur(14px);
  -webkit-backdrop-filter: saturate(180%) blur(14px);
  border-bottom: var(--hair) solid transparent;
  transition: border-color 0.3s var(--ease), background 0.3s var(--ease);
}
.nav[data-stuck="true"] { border-bottom-color: var(--rule); }

.nav__in {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  height: var(--nav-h);
}

.wordmark {
  font-family: var(--mono);
  font-size: 12.5px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  font-weight: 500;
  white-space: nowrap;
}
.wordmark span { color: var(--ink-3); }
/* On the narrowest phones the nowrap wordmark pushed the menu button past
   the viewport edge. Drop the role suffix; the name still identifies it. */
@media (max-width: 440px) { .wordmark span { display: none; } }

.nav__links { display: none; gap: 34px; align-items: center; }
@media (min-width: 860px) { .nav__links { display: flex; } }

.nav__link {
  font-family: var(--mono);
  font-size: 11.5px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-2);
  position: relative;
  padding-block: 4px;
  transition: color 0.22s var(--ease);
}
.nav__link::after {
  content: "";
  position: absolute; left: 0; bottom: 0;
  width: 100%; height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.32s var(--ease);
}
.nav__link:hover { color: var(--ink); }
.nav__link:hover::after,
.nav__link[aria-current="page"]::after { transform: scaleX(1); }
.nav__link[aria-current="page"] { color: var(--ink); }

/* Availability pill */
/* The availability pill is the loudest thing in the bar on purpose: blue
   outline, real 600 weight, and a 2px rule. Everything else beside it stays
   a hairline so this reads first. */
.avail {
  display: none;
  align-items: center;
  gap: 9px;
  border: 2px solid var(--accent-text);
  border-radius: 100px;
  padding: 8px 16px 8px 13px;
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--accent-text);
  white-space: nowrap;
}
@media (min-width: 620px) { .avail { display: inline-flex; } }

.dot {
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--accent-text);
  flex: none;
  position: relative;
}
.dot::after {
  content: "";
  position: absolute; inset: -4px;
  border-radius: 50%;
  border: 1px solid var(--accent-text);
  opacity: 0;
  animation: pulse 2.6s var(--ease) infinite;
}
@keyframes pulse {
  0%   { opacity: 0.7; transform: scale(0.5); }
  70%  { opacity: 0;   transform: scale(1.15); }
  100% { opacity: 0;   transform: scale(1.15); }
}

/* Mobile menu */
.burger { display: grid; gap: 5px; padding: 8px; margin-right: -8px; }
@media (min-width: 860px) { .burger { display: none; } }
.burger i { display: block; width: 20px; height: 1.5px; background: var(--ink); transition: transform 0.3s var(--ease), opacity 0.2s; }
.burger[aria-expanded="true"] i:nth-child(1) { transform: translateY(6.5px) rotate(45deg); }
.burger[aria-expanded="true"] i:nth-child(2) { opacity: 0; }
.burger[aria-expanded="true"] i:nth-child(3) { transform: translateY(-6.5px) rotate(-45deg); }

.drawer {
  display: grid;
  overflow: hidden;
  grid-template-rows: 0fr;
  transition: grid-template-rows 0.42s var(--ease);
  border-top: var(--hair) solid transparent;
}
.drawer[data-open="true"] { grid-template-rows: 1fr; border-top-color: var(--rule); }
.drawer > div { min-height: 0; }
@media (min-width: 860px) { .drawer { display: none; } }

.drawer a {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  padding: 18px 0;
  border-bottom: var(--hair) solid var(--rule-soft);
  font-size: 1.5rem;
  letter-spacing: -0.03em;
  font-weight: 500;
}
.drawer a:last-child { border-bottom: 0; }
.drawer a span { font-family: var(--mono); font-size: 11px; color: var(--ink-3); letter-spacing: 0.1em; }

/* =========================================================================
   Hero
   ========================================================================= */

/* The hero is sized to end where the credentials band begins, so a 16:9
   desktop shows the whole statement plus the band without scrolling.
   Every vertical step below is min(vw, vh): the vw term keeps the original
   proportions on tall screens, and the vh term takes over on short, wide
   laptops where a purely width-driven scale overflows. */
.hero {
  display: flex;
  flex-direction: column;
  min-height: calc(100vh - var(--nav-h) - var(--ticker-h));
  padding-top: clamp(28px, min(8vw, 5.5vh), 118px);
  padding-bottom: clamp(24px, min(5vw, 4vh), 76px);
}
.hero > .shell { display: flex; flex-direction: column; flex: 1; }

.hero__meta {
  display: flex;
  flex-wrap: wrap;
  gap: 12px 28px;
  justify-content: space-between;
  padding-bottom: 26px;
  border-bottom: var(--hair) solid var(--rule);
  margin-bottom: clamp(22px, min(4.4vw, 3.6vh), 60px);
}

.hero__h {
  margin-top: auto;          /* pairs with .hero__foot to split leftover height */
  font-size: clamp(2.4rem, min(8.1vw, 11.5vh), 8.4rem);
  line-height: 0.9;
  letter-spacing: -0.045em;
  text-transform: uppercase;
  font-weight: 700;
  max-width: 15ch;
}

/* The second, quieter half of the statement */
.hero__sub {
  margin-top: clamp(16px, min(3vw, 2.5vh), 44px);
  font-size: clamp(1.2rem, min(3.1vw, 4vh), 2.9rem);
  line-height: 1.1;
  letter-spacing: -0.035em;
  font-weight: 400;
  color: var(--ink-2);
  max-width: 26ch;
}
.hero__sub b { font-weight: 500; color: var(--ink); }
.hero__sub em { font-style: normal; color: var(--accent-text); }

.hero__foot {
  margin-top: auto;
  padding-top: clamp(24px, min(5.4vw, 4.2vh), 84px);
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: 32px;
}

.hero__blurb {
  max-width: 52ch;
  color: var(--ink-2);
  font-size: clamp(0.98rem, 1.1vw, 1.08rem);
  line-height: 1.55;
}

/* =========================================================================
   Buttons
   ========================================================================= */

.btn {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  padding: 15px 24px;
  border-radius: 100px;
  border: var(--hair) solid var(--ink);
  background: var(--ink);
  color: var(--paper);
  font-family: var(--mono);
  font-size: 11.5px;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  white-space: nowrap;
  transition: background 0.26s var(--ease), color 0.26s var(--ease),
              border-color 0.26s var(--ease), transform 0.26s var(--ease);
}
.btn:hover { background: var(--accent); border-color: var(--accent); color: #fff; transform: translateY(-2px); }
.btn svg { transition: transform 0.3s var(--ease); flex: none; }
.btn:hover svg { transform: translate(3px, -3px); }
.btn--ghost { background: transparent; color: var(--ink); border-color: var(--rule); }
.btn--ghost:hover { background: var(--ink); border-color: var(--ink); color: var(--paper); }
.btn--down:hover svg { transform: translateY(3px); }
.btn--light { background: var(--paper); border-color: var(--paper); color: var(--ink); }
.btn--light:hover { background: var(--accent); border-color: var(--accent); color: #fff; }


/* =========================================================================
   Credentials marquee
   ========================================================================= */

.ticker {
  background: var(--invert-bg);
  color: var(--invert-fg);
  padding-block: 18px;
  overflow: hidden;
  user-select: none;
}

.ticker__track {
  display: flex;
  width: max-content;
  animation: slide 46s linear infinite;
}
.ticker:hover .ticker__track { animation-play-state: paused; }

.ticker__group { display: flex; flex: none; }

.ticker__item {
  display: inline-flex;
  align-items: center;
  gap: 14px;
  padding-inline: 22px;
  font-family: var(--mono);
  font-size: clamp(11px, 0.86vw, 13px);
  letter-spacing: 0.09em;
  text-transform: uppercase;
  white-space: nowrap;
}
.ticker__item::before {
  content: "";
  width: 5px; height: 5px; border-radius: 50%;
  background: var(--accent-inv);
  flex: none;
}

@keyframes slide {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(-50%, 0, 0); }
}

/* =========================================================================
   Work — case study cards
   Structure follows the supplied reference: image block on top, stacked
   content beneath, pill CTA last. Surface treatment stays with the site's
   editorial language (hairline borders, square corners, no shadow) so the
   section sits with the philosophy grid directly below it.
   ========================================================================= */

.cases {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: clamp(18px, 2.1vw, 30px);
}
@media (min-width: 900px) {
  .cases { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  /* The lead case study runs the full width, image beside the copy. */
  .case--featured { grid-column: 1 / -1; grid-template-columns: 1.12fr 1fr; grid-template-rows: auto; }
}

.case {
  display: grid;
  grid-template-rows: auto 1fr;
  background: var(--paper);
  border: var(--hair) solid var(--rule);
  overflow: hidden;
  color: inherit;
  transition: border-color 0.34s var(--ease), background 0.34s var(--ease);
}
a.case:hover,
a.case:focus-visible { border-color: var(--accent-text); background: var(--paper-deep); }

/* --- media ------------------------------------------------------------- */

.case__media {
  position: relative;
  aspect-ratio: 16 / 10;
  display: grid;
  place-items: center;
  overflow: hidden;
  border-bottom: var(--hair) solid var(--rule);
  background:
    repeating-linear-gradient(-45deg, transparent 0 11px, var(--rule) 11px 12px),
    var(--paper-deep);
}
.case__media img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.7s var(--ease);
}
a.case:hover .case__media img { transform: scale(1.035); }

@media (min-width: 900px) {
  .case--featured .case__media {
    aspect-ratio: auto;
    height: 100%;
    min-height: clamp(320px, 30vw, 460px);
    border-bottom: 0;
    border-right: var(--hair) solid var(--rule);
  }
}

/* --- body -------------------------------------------------------------- */

.case__body {
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding: clamp(20px, 2.2vw, 30px);
}
@media (min-width: 900px) {
  .case--featured .case__body {
    padding: clamp(30px, 3.2vw, 52px);
    gap: 22px;
  }
}

.case__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 10px 18px;
}

.case__num {
  font-family: var(--mono);
  font-size: 11.5px;
  letter-spacing: 0.1em;
  color: var(--accent-text);
}

/* Card tags read as discrete chips rather than one dot-separated string. */
.tags {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  justify-content: flex-end;
}
.tag {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--ink-2);
  border: var(--hair) solid var(--rule);
  border-radius: 100px;
  padding: 5px 11px;
  line-height: 1;
  white-space: nowrap;
  transition: border-color 0.3s var(--ease);
}
a.case:hover .tag { border-color: var(--ink-3); }

.case__title {
  font-size: clamp(1.24rem, 1.95vw, 1.62rem);
  letter-spacing: -0.035em;
  font-weight: 500;
  line-height: 1.08;
  text-wrap: balance;
  transition: color 0.3s var(--ease);
}
a.case:hover .case__title { color: var(--accent-text); }

@media (min-width: 900px) {
  .case--featured .case__title { font-size: clamp(1.9rem, 3.1vw, 3rem); }
}

/* --- pill cta (borrowed from the reference) ---------------------------- */

.case__cta {
  margin-top: auto;
  align-self: flex-start;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 13px 21px;
  border-radius: 100px;
  border: var(--hair) solid var(--ink);
  background: var(--ink);
  color: var(--paper);
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  white-space: nowrap;
  transition: background 0.26s var(--ease), border-color 0.26s var(--ease),
              color 0.26s var(--ease);
}
.case__cta svg { transition: transform 0.3s var(--ease); flex: none; }
a.case:hover .case__cta { background: var(--accent); border-color: var(--accent); color: #fff; }
a.case:hover .case__cta svg { transform: translate(3px, -3px); }

/* --- not yet written --------------------------------------------------- */

.case--soon .case__title { color: var(--ink-2); font-weight: 400; }
.case--soon .case__num   { color: var(--ink-3); }
.case--soon .case__cta {
  background: transparent;
  border-color: var(--rule);
  color: var(--ink-3);
}

/* =========================================================================
   Philosophy — numbered hairline grid
   ========================================================================= */

.grid-cards {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  border-top: var(--hair) solid var(--rule);
  border-left: var(--hair) solid var(--rule);
}
@media (min-width: 640px)  { .grid-cards { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1080px) { .grid-cards { grid-template-columns: repeat(3, minmax(0, 1fr)); } }

.gcard {
  border-right: var(--hair) solid var(--rule);
  border-bottom: var(--hair) solid var(--rule);
  padding: clamp(24px, 2.6vw, 40px);
  display: flex;
  flex-direction: column;
  gap: 14px;
  min-height: 0;
  position: relative;
  background: transparent;
  transition: background 0.34s var(--ease);
}
.gcard:hover { background: var(--paper-deep); }
@media (min-width: 640px) { .gcard { min-height: clamp(230px, 21vw, 290px); } }

.gcard__num {
  font-family: var(--mono);
  font-size: 11.5px;
  letter-spacing: 0.1em;
  color: var(--accent-text);
  margin-bottom: clamp(30px, 5vw, 82px);   /* the negative space, deliberately */
}

.gcard__h {
  font-size: clamp(1.12rem, 1.55vw, 1.42rem);
  letter-spacing: -0.03em;
  font-weight: 500;
  line-height: 1.15;
  text-wrap: balance;
}

.gcard__p {
  color: var(--ink-2);
  font-size: 0.95rem;
  line-height: 1.55;
  max-width: 40ch;
}

/* =========================================================================
   Numbered step list — used inside the radar's detail panel
   ========================================================================= */

.ops__list { display: grid; gap: 0; }
.ops__list li {
  display: grid;
  grid-template-columns: 26px minmax(0, 1fr);
  gap: 14px;
  padding-block: 11px;
  border-bottom: var(--hair) solid var(--rule-soft);
  color: var(--ink-2);
  font-size: 0.96rem;
  line-height: 1.5;
}
.ops__list li:last-child { border-bottom: 0; }
.ops__list li::before {
  content: counter(step, decimal-leading-zero);
  counter-increment: step;
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: 0.08em;
  color: var(--ink-3);
  padding-top: 4px;
}
.ops__list { counter-reset: step; }

/* =========================================================================
   Contact
   ========================================================================= */

.contact { background: var(--accent); color: #fff; }

.contact__h {
  font-size: clamp(2.6rem, 9vw, 8.6rem);
  line-height: 0.88;
  letter-spacing: -0.05em;
  font-weight: 600;
  text-transform: uppercase;
}


/* =========================================================================
   Footer
   ========================================================================= */

.foot { background: var(--invert-bg); color: var(--invert-fg-2); padding-block: 36px; }
.foot__in {
  display: flex;
  flex-wrap: wrap;
  gap: 14px 32px;
  align-items: center;
  justify-content: space-between;
}
.foot a { color: var(--invert-fg); transition: color 0.24s var(--ease); }
.foot a:hover { color: var(--accent-inv); }

/* Oversized signature wordmark */
.sig {
  font-size: clamp(3.4rem, 15.5vw, 15rem);
  line-height: 0.78;
  letter-spacing: -0.055em;
  font-weight: 700;
  text-transform: uppercase;
  color: var(--invert-rule);
  padding-top: clamp(30px, 4vw, 60px);
  padding-bottom: clamp(10px, 1.4vw, 20px);
  white-space: nowrap;
  overflow: hidden;
  user-select: none;
}

/* =========================================================================
   Case study pages
   ========================================================================= */

.cs-hero { padding-top: clamp(48px, 6vw, 92px); padding-bottom: clamp(40px, 4.6vw, 70px); }

.cs-hero__h {
  font-size: clamp(2.2rem, 6.4vw, 6.1rem);
  line-height: 0.93;
  letter-spacing: -0.045em;
  font-weight: 600;
  text-transform: uppercase;
  max-width: 17ch;
  margin-top: 26px;
}

.cs-hero__lede {
  margin-top: clamp(24px, 2.8vw, 40px);
  font-size: clamp(1.1rem, 2vw, 1.6rem);
  line-height: 1.32;
  letter-spacing: -0.028em;
  color: var(--ink-2);
  max-width: 34ch;
}

/* Spec table */
.spec {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 190px), 1fr));
  border-top: var(--hair) solid var(--rule);
  margin-top: clamp(40px, 4.6vw, 70px);
}
.spec > div {
  padding: 22px 22px 22px 0;
  border-bottom: var(--hair) solid var(--rule);
}
.spec dt { margin-bottom: 10px; }
.spec dd {
  margin: 0;
  font-size: 0.98rem;
  letter-spacing: -0.02em;
  line-height: 1.45;
}

/* Visual placeholder blocks — swap for real screenshots */
.shot {
  border: var(--hair) solid var(--rule);
  background:
    repeating-linear-gradient(-45deg,
      transparent 0 11px,
      var(--rule) 11px 12px),
    var(--paper-deep);
  aspect-ratio: 16 / 9;
  display: grid;
  place-items: center;
  position: relative;
  overflow: hidden;
}
.shot--tall { aspect-ratio: 4 / 3; }
.shot__tag {
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-3);
  background: var(--paper);
  border: var(--hair) solid var(--rule);
  padding: 8px 14px;
  text-align: center;
  max-width: 80%;
}
.shot img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.shot-pair {
  display: grid;
  gap: var(--hair);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 320px), 1fr));
  margin-top: clamp(28px, 3vw, 44px);
}

/* Case study body blocks */
.cs-block {
  display: grid;
  gap: 22px;
  padding-block: clamp(36px, 4vw, 62px);
  border-top: var(--hair) solid var(--rule);
}
@media (min-width: 900px) {
  .cs-block { grid-template-columns: 20% minmax(0, 1fr); gap: 40px; align-items: start; }
}

.cs-block__h {
  font-size: clamp(1.5rem, 2.6vw, 2.15rem);
  letter-spacing: -0.035em;
  font-weight: 500;
  margin-bottom: 18px;
}

.prose {
  font-size: clamp(1.02rem, 1.28vw, 1.18rem);
  line-height: 1.6;
  color: var(--ink-2);
  max-width: 64ch;
  letter-spacing: -0.014em;
}
.prose p + p { margin-top: 18px; }
.prose strong { color: var(--ink); font-weight: 500; }

/* Checklist-style item lists */
.items { margin-top: 8px; border-top: var(--hair) solid var(--rule-soft); max-width: 72ch; }
.items li {
  display: grid;
  grid-template-columns: 30px minmax(0, 1fr);
  gap: 14px;
  padding-block: 14px;
  border-bottom: var(--hair) solid var(--rule-soft);
  font-size: clamp(0.98rem, 1.16vw, 1.08rem);
  line-height: 1.5;
  color: var(--ink-2);
  letter-spacing: -0.014em;
}
.items li::before {
  content: counter(i, decimal-leading-zero);
  counter-increment: i;
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: 0.08em;
  color: var(--ink-3);
  padding-top: 5px;
}
.items { counter-reset: i; }

/* Results get the accent treatment */
.items--win li::before { content: "→"; font-size: 13px; color: var(--accent-text); padding-top: 1px; }
.items--win li { color: var(--ink); }

/* Prev / next */
.pager { border-top: var(--hair) solid var(--rule); }
.pager__link {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 24px;
  padding-block: clamp(30px, 3.4vw, 48px);
  border-bottom: var(--hair) solid var(--rule);
  transition: color 0.26s var(--ease), padding-inline 0.34s var(--ease);
}
.pager__link:hover { color: var(--accent-text); padding-inline: 10px; }
.pager__name {
  font-size: clamp(1.3rem, 2.8vw, 2.3rem);
  letter-spacing: -0.038em;
  font-weight: 500;
  text-align: right;
  text-wrap: balance;
}

/* =========================================================================
   Scroll reveal
   ========================================================================= */

[data-reveal] {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity 0.7s var(--ease), transform 0.7s var(--ease);
  transition-delay: var(--delay, 0ms);
}
[data-reveal].is-in { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
  [data-reveal] { opacity: 1; transform: none; }
  .ticker__track { animation: none; }
}

/* =========================================================================
   Print
   ========================================================================= */

@media print {
  .nav, .ticker, .contact, .foot, .pager, .btn { display: none !important; }
  body { background: #fff; color: #000; }
  [data-reveal] { opacity: 1 !important; transform: none !important; }
}

/* Hero call-to-action cluster */
.hero__cta { display: flex; gap: 12px; flex-wrap: wrap; }


/* One-line summary on cards that have a write-up behind them. */
.case__lede {
  color: var(--ink-2);
  font-size: 0.95rem;
  line-height: 1.5;
  max-width: 48ch;
}
@media (min-width: 900px) {
  .case--featured .case__lede {
    font-size: clamp(1rem, 1.18vw, 1.14rem);
    max-width: 34ch;
  }
}

/* =========================================================================
   Theme toggle
   The icon shows the theme you would switch TO, which is why the moon
   appears in light mode. Both the media query and the [data-theme] rule
   are needed so the icon is right for viewers on the system default too.
   ========================================================================= */

.nav__end {
  display: flex;
  align-items: center;
  gap: 10px;
}

/* Neutral by design — the action sits beside the status without competing
   with it. Hidden on narrower bars, where the drawer carries it instead. */
.nav__cv {
  display: none;
  align-items: center;
  gap: 8px;
  padding: 9px 15px;
  border-radius: 100px;
  border: var(--hair) solid var(--rule);
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-2);
  white-space: nowrap;
  transition: color 0.24s var(--ease), border-color 0.24s var(--ease),
              background 0.24s var(--ease);
}
@media (min-width: 1040px) { .nav__cv { display: inline-flex; } }
.nav__cv:hover { color: var(--ink); border-color: var(--ink-3); background: var(--paper-deep); }
.nav__cv svg { flex: none; transition: transform 0.3s var(--ease); }
.nav__cv:hover svg { transform: translateY(2px); }

.themer {
  display: inline-grid;
  place-items: center;
  width: 34px;
  height: 34px;
  flex: none;
  border: var(--hair) solid var(--rule);
  border-radius: 100px;
  color: var(--ink-2);
  transition: color 0.24s var(--ease), border-color 0.24s var(--ease),
              background 0.24s var(--ease);
}
.themer:hover { color: var(--ink); border-color: var(--ink-3); background: var(--paper-deep); }
.themer svg { width: 15px; height: 15px; }

.themer__sun  { display: none; }
.themer__moon { display: block; }

:root[data-theme="dark"] .themer__sun  { display: block; }
:root[data-theme="dark"] .themer__moon { display: none; }

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .themer__sun  { display: block; }
  :root:not([data-theme="light"]) .themer__moon { display: none; }
}

/* Same control as a row inside the mobile drawer */
.drawer__theme {
  display: flex;
  width: 100%;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  padding: 18px 0;
  text-align: left;
  font-size: 1.5rem;
  letter-spacing: -0.03em;
  font-weight: 500;
  color: inherit;
  transition: color 0.24s var(--ease);
}
.drawer__theme:hover { color: var(--accent-text); }
.drawer__theme span {
  font-family: var(--mono);
  font-size: 11px;
  color: var(--ink-3);
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

/* Repaint the page smoothly when the theme flips, but never for anyone who
   has asked for reduced motion (the global reduced-motion block also
   collapses this). */
body { transition: background-color 0.3s var(--ease), color 0.3s var(--ease); }

/* =========================================================================
   Strengths / growth radar
   The plain lists in .radar__data are the source of truth and the no-JS
   view; the script reads them, draws the chart, and swaps the two.
   ========================================================================= */

.radar__switch {
  display: inline-flex;
  gap: 4px;
  padding: 4px;
  border: var(--hair) solid var(--rule);
  border-radius: 100px;
}

.radar__tab {
  padding: 9px 20px;
  border-radius: 100px;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  color: var(--ink-2);
  transition: background 0.26s var(--ease), color 0.26s var(--ease);
}
.radar__tab:hover { color: var(--ink); }
.radar__tab[aria-selected="true"] { background: var(--ink); color: var(--paper); }

/* Strengths mode carries no caption, so collapse the element rather than
   leaving a gap the growth-areas caption would later fill. */
.radar__caption:empty { display: none; }

.radar__caption {
  margin-top: 22px;
  max-width: 56ch;
  color: var(--ink-2);
  font-size: clamp(0.98rem, 1.15vw, 1.1rem);
  line-height: 1.55;
}

.radar__grid {
  margin-top: clamp(30px, 3.4vw, 52px);
  display: grid;
  gap: clamp(28px, 3.5vw, 64px);
  align-items: center;
}
@media (min-width: 980px) {
  .radar__grid { grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr); }
}

.radar__plot svg { width: 100%; height: auto; display: block; overflow: visible; }

/* --- chart parts --------------------------------------------------------- */

.radar__ring   { fill: none; stroke: var(--rule); stroke-width: 1; }
.radar__spoke  { stroke: var(--rule); stroke-width: 1; }

.radar__shape {
  fill: var(--accent-text);
  fill-opacity: 0.11;
  stroke: var(--accent-text);
  stroke-width: 1.6;
  stroke-linejoin: round;
  transition: fill-opacity 0.4s var(--ease);
}
.radar[data-mode="growth"] .radar__shape { fill: var(--ember); stroke: var(--ember); }

.radar__dot {
  fill: var(--paper);
  stroke: var(--accent-text);
  stroke-width: 1.6;
  transition: fill 0.24s var(--ease), r 0.24s var(--ease);
}
.radar[data-mode="growth"] .radar__dot { stroke: var(--ember); }

.radar__label {
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  fill: var(--ink-2);
  transition: fill 0.24s var(--ease);
}

/* one interactive group per axis: spoke + dot + label */
.radar__axis { cursor: pointer; outline: none; }
.radar__axis:hover .radar__label,
.radar__axis[data-active="true"] .radar__label { fill: var(--ink); }
.radar__axis:hover .radar__dot,
.radar__axis[data-active="true"] .radar__dot { fill: var(--accent-text); }
.radar[data-mode="growth"] .radar__axis:hover .radar__dot,
.radar[data-mode="growth"] .radar__axis[data-active="true"] .radar__dot { fill: var(--ember); }

/* transparent (not none) so it still receives pointer events */
.radar__hit { fill: transparent; stroke: none; }

.radar__axis:focus-visible .radar__hit {
  fill: var(--accent-text);
  fill-opacity: 0.07;
  stroke: var(--accent-text);
  stroke-width: 1.5;
  stroke-dasharray: 3 3;
}
.radar[data-mode="growth"] .radar__axis:focus-visible .radar__hit {
  fill: var(--ember);
  stroke: var(--ember);
}

/* --- detail panel -------------------------------------------------------- */

.radar__detail {
  border-top: var(--hair) solid var(--rule);
  padding-top: clamp(22px, 2.4vw, 32px);
  min-height: clamp(220px, 24vw, 300px);
}

.radar__detail h4 {
  font-size: clamp(1.3rem, 2.2vw, 1.85rem);
  letter-spacing: -0.035em;
  font-weight: 500;
  line-height: 1.1;
  margin-bottom: 16px;
  text-wrap: balance;
}

.radar__detail p {
  color: var(--ink-2);
  font-size: clamp(0.98rem, 1.2vw, 1.1rem);
  line-height: 1.6;
  max-width: 52ch;
}

.radar__detail .ops__list { margin-top: 20px; }

/* --- plain-list fallback ------------------------------------------------- */

.radar__set + .radar__set { margin-top: clamp(40px, 4.5vw, 70px); }

.radar__setname {
  font-family: var(--mono);
  font-size: 11.5px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-3);
  font-weight: 400;
  margin-bottom: 20px;
}

.radar__list { border-top: var(--hair) solid var(--rule); }
.radar__list > li {
  padding-block: clamp(20px, 2.2vw, 30px);
  border-bottom: var(--hair) solid var(--rule);
}
.radar__list h4 {
  font-size: clamp(1.15rem, 1.9vw, 1.55rem);
  letter-spacing: -0.032em;
  font-weight: 500;
  margin-bottom: 12px;
}
.radar__list .radar__body p {
  color: var(--ink-2);
  font-size: 1rem;
  line-height: 1.6;
  max-width: 66ch;
}

/* =========================================================================
   Contact form + details
   Everything here sits on the accent band, so colours are white-on-accent
   rather than token-driven — the band is blue in both themes.
   ========================================================================= */

.contact__layout {
  margin-top: clamp(40px, 4.6vw, 72px);
  display: grid;
  gap: clamp(36px, 4vw, 68px);
  align-items: start;
}
@media (min-width: 900px) {
  .contact__layout { grid-template-columns: minmax(0, 1.15fr) minmax(0, 0.85fr); }
}

.cform { display: grid; gap: clamp(18px, 2vw, 24px); }

.cform__row { display: grid; gap: 9px; }

.cform__label {
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.84);
}
.cform__label span { color: rgba(255, 255, 255, 0.84); }   /* 4.96:1 on the accent band */

.cform__input {
  width: 100%;
  font-family: var(--sans);
  font-size: 1rem;
  letter-spacing: -0.015em;
  color: #fff;
  background: rgba(255, 255, 255, 0.08);
  border: var(--hair) solid rgba(255, 255, 255, 0.34);
  border-radius: 2px;
  padding: 14px 16px;
  transition: border-color 0.24s var(--ease), background 0.24s var(--ease);
}
.cform__input::placeholder { color: rgba(255, 255, 255, 0.55); }
.cform__input:hover { border-color: rgba(255, 255, 255, 0.55); }
.cform__input:focus {
  outline: none;
  border-color: #fff;
  background: rgba(255, 255, 255, 0.14);
}
.cform__input:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }

/* the browser's own invalid styling is too shouty; only flag after a try */
.cform[data-tried="true"] .cform__input:invalid { border-color: #FFD9CE; }

.cform__area { resize: vertical; min-height: 108px; line-height: 1.5; }

.cform__select {
  appearance: none;
  -webkit-appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' fill='none'%3E%3Cpath d='M1 1.5 6 6.5l5-5' stroke='%23ffffff' stroke-width='1.4'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 16px center;
  padding-right: 44px;
}
.cform__select option { color: var(--ink); background: var(--paper); }

.cform__foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 16px 20px;
  margin-top: 4px;
}

.cform__status {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.84);
}
.cform__status[data-state="error"] { color: #FFD9CE; }

/* --- aside: résumé + details -------------------------------------------- */

.contact__aside { display: grid; gap: clamp(28px, 3vw, 40px); }

.contact__resume { justify-self: start; }

.contact__details {
  display: grid;
  gap: 20px;
  margin: 0;
  padding-top: clamp(24px, 2.6vw, 34px);
  border-top: var(--hair) solid rgba(255, 255, 255, 0.28);
}
.contact__details > div { display: grid; gap: 7px; }
.contact__details dt { color: rgba(255, 255, 255, 0.84); }
.contact__details dd { margin: 0; }
.contact__details a {
  font-size: clamp(1rem, 1.3vw, 1.12rem);
  letter-spacing: -0.02em;
  position: relative;
  width: fit-content;
  padding-bottom: 2px;
  display: inline-block;
}
.contact__details a::after {
  content: "";
  position: absolute; left: 0; bottom: 0;
  width: 100%; height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: right;
  transition: transform 0.34s var(--ease);
}
.contact__details a:hover::after { transform: scaleX(1); transform-origin: left; }

/* =========================================================================
   Contact pitch
   One paragraph stating the case, ending on "then" so the headline below
   completes the sentence.
   ========================================================================= */

.pitch {
  max-width: 54ch;
  margin-bottom: clamp(24px, 2.8vw, 40px);
  color: #fff;
  font-size: clamp(1.06rem, 1.6vw, 1.42rem);
  line-height: 1.38;
  letter-spacing: -0.024em;
  text-wrap: pretty;
}

/* =========================================================================
   Contact portrait
   Vertical on desktop where the aside column has the height for it; square
   on narrow screens, so a tall crop does not push the form off the page.
   object-position sits high in the frame, which is where a head lands in a
   vertical portrait.
   ========================================================================= */

.contact__photo {
  position: relative;
  margin: 0;
  width: 100%;
  max-width: 360px;
  aspect-ratio: 3 / 4;
  overflow: hidden;
  display: grid;
  place-items: center;
  border: var(--hair) solid rgba(255, 255, 255, 0.34);
  background:
    repeating-linear-gradient(-45deg, transparent 0 11px, rgba(255, 255, 255, 0.16) 11px 12px),
    rgba(255, 255, 255, 0.07);
}

.contact__photo img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 22%;
}

/* Same trick as the case study slots: if the file is not there the <img>
   removes itself and this placeholder shows instead of a broken icon. */
.contact__photo figcaption {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  line-height: 1.5;
  text-align: center;
  color: rgba(255, 255, 255, 0.9);
  background: rgba(0, 0, 0, 0.16);
  border: var(--hair) solid rgba(255, 255, 255, 0.34);
  padding: 9px 13px;
  max-width: 84%;
}

@media (max-width: 899px) {
  .contact__photo { aspect-ratio: 1 / 1; max-width: none; }
}

/* --- Avatar variant -------------------------------------------------------
   Case study pages show the portrait as a round profile picture rather than
   the full frame the home page carries. Doubled class so these win over the
   base rules and the narrow-screen override regardless of source order. */

.contact__photo.contact__photo--avatar {
  width: clamp(104px, 11vw, 136px);
  max-width: none;
  aspect-ratio: 1;
  border-radius: 50%;
  justify-self: start;
}

/* A vertical frame crops tighter here, so sit a little lower for a head-and-
   shoulders read rather than a head floating at the top of the circle. */
.contact__photo.contact__photo--avatar img { object-position: center 26%; }

/* The placeholder path text cannot fit legibly in a circle this size; the
   hatched fill alone signals the empty slot. */
.contact__photo.contact__photo--avatar figcaption { display: none; }
