:root {
  --paper: #f3f5f7;
  --paper-deep: #dfe5ea;
  --folder-fill: #ffdcd7;
  --folder-stack: #efb3ab;
  --ink: #151918;
  --muted: #596369;
  --shadow: #26333b;
  --red: #f05d4f;
  --blue: #5074e9;
  --green: #42a875;
  --yellow: #f2c735;
  --display: "Cabinet Grotesk", "Helvetica Neue", Arial, sans-serif;
  --body: "Cabinet Grotesk", "Helvetica Neue", Arial, sans-serif;
  --pad: clamp(20px, 4.2vw, 64px);
  --header: 72px;
  --border: 2px solid var(--ink);
}

* { box-sizing: border-box; }
html { scroll-behavior: auto; }
body { margin: 0; background: var(--paper); color: var(--ink); font-family: var(--body); font-size: 18px; line-height: 1.45; }
a { color: inherit; }
button { color: inherit; font: inherit; }
img { display: block; max-width: 100%; }
:focus-visible { outline: 4px solid var(--ink); outline-offset: 4px; }
.visually-hidden { position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }

.skip-link { position: fixed; left: 12px; top: 12px; z-index: 100; background: var(--ink); color: white; padding: 12px 18px; transform: translateY(-150%); }
.skip-link:focus { transform: none; }

.site-header { height: var(--header); display: flex; align-items: center; justify-content: space-between; padding: 0 var(--pad); border-bottom: var(--border); background: var(--paper); position: relative; z-index: 20; }
.wordmark { font-family: var(--display); font-weight: 800; text-decoration: none; letter-spacing: -.025em; }
.site-header nav { display: flex; align-items: center; gap: clamp(18px, 3vw, 42px); }
.site-header nav a { min-height: 44px; display: inline-flex; align-items: center; text-decoration-thickness: 2px; text-underline-offset: 5px; }

.hero { min-height: calc(100svh - var(--header)); display: grid; grid-template-columns: minmax(0, 1.1fr) minmax(360px, .9fr); overflow: hidden; border-bottom: var(--border); }
.hero-copy { padding: clamp(64px, 10vh, 120px) var(--pad); align-self: center; }
.hero-strapline { margin: 0 0 18px !important; max-width: none !important; font-size: .9rem !important; font-weight: 800; letter-spacing: .08em !important; line-height: 1.2 !important; text-transform: uppercase; }
.hero h1 { margin: 0; font-family: var(--display); font-size: clamp(3.4rem, 8vw, 8.4rem); font-weight: 900; line-height: .86; letter-spacing: -.055em; }
.hero-copy > p { margin: clamp(26px, 4vw, 44px) 0 0; max-width: 17ch; font-size: clamp(1.75rem, 3.5vw, 3.8rem); line-height: 1.02; letter-spacing: -.035em; }
.text-link { margin-top: 36px; min-height: 44px; display: inline-flex; align-items: center; gap: 12px; font-weight: 600; text-underline-offset: 6px; }
.hero-actions { margin-top: 36px; display: flex; flex-wrap: wrap; align-items: center; gap: 16px 24px; }
.hero-actions .text-link { margin-top: 0; }
.hero-primary {
  min-height: 58px; padding: 14px 28px 14px 26px;
  display: inline-flex; align-items: center; gap: 16px;
  border: 2.5px solid var(--ink); border-radius: 8px;
  background: var(--yellow); color: var(--ink);
  box-shadow: 6px 6px 0 var(--ink);
  font-weight: 800; font-size: 1.18rem; letter-spacing: -.01em; text-decoration: none;
  transition: transform var(--t-quick) var(--ease-drawer), box-shadow var(--t-quick) var(--ease-drawer);
}
.hero-primary::after {
  content: ""; width: 28px; height: 17px; flex: 0 0 auto;
  background: var(--ink);
  clip-path: polygon(0 40%, 62% 40%, 62% 0, 100% 50%, 62% 100%, 62% 60%, 0 60%);
  transition: translate var(--t-quick) var(--ease-drawer);
}
.hero-primary:hover { transform: translate(-2px, -2px); box-shadow: 8px 8px 0 var(--ink); }
.hero-primary:hover::after { translate: 3px 0; }
.hero-primary:active { transform: translate(5px, 5px); box-shadow: 1px 1px 0 var(--ink); transition-duration: 60ms; }

.cabinet { position: relative; min-height: 100%; background: var(--blue); border-left: var(--border); overflow: hidden; display: grid; place-items: center; padding: 8vw 5vw; }
.cabinet::before { content: ""; position: absolute; inset: 0; opacity: .13; background-image: repeating-linear-gradient(90deg, transparent 0 32px, rgba(23,25,22,.5) 33px 34px), repeating-linear-gradient(0deg, transparent 0 32px, rgba(23,25,22,.35) 33px 34px); }
.cabinet-top { position: absolute; top: 11%; left: 9%; width: 82%; height: 13%; border: var(--border); background: #dce2e6; box-shadow: 12px 12px 0 var(--shadow); }
.cabinet-drawer { position: relative; width: min(84%, 620px); aspect-ratio: 1.25; background: #dce2e6; border: 3px solid var(--ink); box-shadow: 20px 24px 0 var(--shadow); transform: rotate(1.7deg); }
.cabinet-label { position: absolute; top: 18%; left: 50%; translate: -50% 0; width: 52%; padding: 14px; border: 3px solid var(--ink); background: var(--paper); text-align: center; font-family: var(--display); font-size: clamp(.8rem, 1.3vw, 1.2rem); line-height: 1.25; }
.cabinet-handle { position: absolute; top: 58%; left: 50%; translate: -50% 0; width: 44%; height: 14%; border: 4px solid var(--ink); border-radius: 99px; background: #b7c0c6; box-shadow: inset 0 -8px 0 rgba(21,25,24,.16); }
.cabinet-tabs { position: absolute; inset: auto 7% 100%; display: flex; align-items: end; justify-content: space-between; }
.cabinet-tabs i { width: 22%; height: 64px; border: 3px solid var(--ink); border-bottom: 0; border-radius: 8px 8px 0 0; }
.cabinet-tabs i:nth-child(1) { background: var(--red); height: 46px; }
.cabinet-tabs i:nth-child(2) { background: var(--blue); height: 74px; }
.cabinet-tabs i:nth-child(3) { background: var(--green); height: 58px; }
.cabinet-tabs i:nth-child(4) { background: var(--yellow); height: 88px; }
.cabinet > p { position: absolute; right: 5%; bottom: 4%; margin: 0; font-family: var(--display); text-align: right; font-size: clamp(1rem, 1.5vw, 1.35rem); line-height: 1.15; }

.experience { padding: clamp(64px, 7vw, 104px) var(--pad) clamp(80px, 10vw, 150px); background: var(--paper-deep); }

.drawer { max-width: 1400px; margin: 0 auto; filter: drop-shadow(24px 28px 0 rgba(38,51,59,.18)); }
.capability-tabs { display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; padding: 0 4%; align-items: end; }
.capability-tab { min-height: 84px; border: var(--border); border-bottom: 0; border-radius: 12px 12px 0 0; padding: 16px 18px 30px; display: flex; flex-direction: column; justify-content: flex-end; align-items: flex-start; text-align: left; cursor: pointer; transform: translateY(18px); transition: transform 220ms cubic-bezier(.2,.8,.2,1), min-height 220ms cubic-bezier(.2,.8,.2,1); }
.capability-tab span { font-family: var(--display); font-size: clamp(.94rem, 1.45vw, 1.28rem); font-weight: 800; line-height: 1; letter-spacing: -.02em; }
.capability-tab small { margin-top: 7px; font-size: .82rem; line-height: 1.1; opacity: .78; }
.capability-tab:hover { transform: translateY(10px); }
.capability-tab[aria-selected="true"] { padding-bottom: 16px; min-height: 96px; transform: translateY(2px); z-index: 2; }
/* --tab-colour is inert here and used by the mobile tab stack, where a closed
   folder shows only its coloured edge instead of a full block of colour. */
.tab-red { --tab-colour: var(--red); --tab-tint: #ffdcd7; background: var(--red); }
.tab-blue { --tab-colour: var(--blue); --tab-tint: #dfe6ff; background: var(--blue); color: white; }
.tab-green { --tab-colour: var(--green); --tab-tint: #d9f0e3; background: var(--green); color: white; }
.tab-yellow { --tab-colour: var(--yellow); --tab-tint: #fff0b8; background: var(--yellow); }

.folder { position: relative; min-height: 680px; border: 3px solid var(--ink); background: var(--folder-fill); padding: clamp(28px, 4vw, 58px); transition: background-color 220ms ease; }
.folder[data-color="red"] { --folder-fill: #ffdcd7; --folder-stack: #efb3ab; }
.folder[data-color="blue"] { --folder-fill: #dfe6ff; --folder-stack: #afc0f5; }
.folder[data-color="green"] { --folder-fill: #d9f0e3; --folder-stack: #a7d4b9; }
.folder[data-color="yellow"] { --folder-fill: #fff0b8; --folder-stack: #e5cb75; }
.folder::before { content: ""; position: absolute; inset: 14px -14px -14px 14px; border: 3px solid var(--ink); background: var(--folder-stack); z-index: -1; transition: background-color 220ms ease; }






.project-preview { min-width: 0; display: grid; grid-template-columns: minmax(260px, .8fr) minmax(0, 1.2fr); gap: clamp(28px, 4vw, 58px); align-items: center; }
.project-context { margin: 0 0 14px; color: var(--muted); }
.preview-copy h4, .preview-head h4 { margin: 0; font-family: var(--display); font-size: clamp(2.25rem, 3.5vw, 4rem); font-weight: 900; line-height: .92; letter-spacing: -.045em; text-wrap: balance; }
.project-short { margin: 22px 0 0; max-width: 34ch; font-size: clamp(1.15rem, 1.8vw, 1.5rem); line-height: 1.22; }
.project-scope { margin-top: 22px; }
.project-scope > span { display: block; margin-bottom: 9px; color: var(--muted); font-size: .88rem; font-weight: 700; }
/* Two fixed columns. A wrapped flex row leaves a single tag stranded on the
   last line, which reads as unfinished, and it strands a different number on
   every card. A 2-up grid is even at 2 or 4 tags and identical on every card. */
.project-scope ul { margin: 0; padding: 0; display: grid; grid-template-columns: max-content max-content; justify-content: start; gap: 6px; list-style: none; }
.project-scope li { display: inline-flex; align-items: center; padding: 6px 10px 5px; border: 1.5px solid currentColor; border-radius: 2px; background: rgba(255,255,255,.3); font-size: .84rem; font-weight: 500; line-height: 1.12; }
/* An odd count would still strand one, so the last tag spans both columns. */
.project-scope li:nth-child(odd):last-child { grid-column: 1 / -1; }
.project-result { margin-top: 26px; padding-top: 18px; border-top: 1px solid var(--ink); display: grid; gap: 5px; }
.project-result span { color: var(--muted); }
.project-result strong { font-size: 1.08rem; }
.case-link { margin-top: 26px; min-height: 44px; display: inline-flex; align-items: center; gap: 11px; font-weight: 600; text-underline-offset: 6px; transition: gap 180ms ease; }
.case-link:hover { gap: 18px; }
.preview-media { min-width: 0; }

/* Real product captures, framed as the objects a visitor recognises. */
.device-scene { position: relative; min-height: 420px; display: grid; place-items: center; }
.browser-window, .monitor { margin: 0; overflow: hidden; background: #fff; border: 3px solid var(--ink); box-shadow: 14px 14px 0 var(--shadow); }
.browser-window > img, .monitor > img { width: 100%; height: 100%; object-fit: cover; object-position: top; }
.browser-bar, .monitor-bar { height: 32px; border-bottom: 2px solid var(--ink); background: #dedbd4; display: flex; align-items: center; gap: 6px; padding: 0 10px; }
.browser-bar i, .monitor-bar i { width: 9px; height: 9px; border: 1.5px solid var(--ink); border-radius: 50%; }
.browser-bar span { height: 12px; flex: 1; margin-left: 6px; border: 1.5px solid var(--ink); border-radius: 8px; background: var(--paper); }
.browser-scene .browser-window { width: 92%; aspect-ratio: 16 / 10; }
.browser-phone { position: absolute; right: 1%; bottom: 0; width: 25%; height: 65%; transform: rotate(3deg); }
.phone { margin: 0; position: relative; overflow: hidden; border: 7px solid var(--ink); border-radius: 32px; background: var(--ink); box-shadow: 12px 14px 0 rgba(38,51,59,.24); }
.phone::before { content: ""; position: absolute; top: 5px; left: 50%; translate: -50% 0; width: 32%; height: 12px; border-radius: 99px; background: var(--ink); z-index: 2; }
.phone img { width: 100%; height: 100%; object-fit: cover; object-position: top; border-radius: 22px; }
.phones { grid-template-columns: repeat(3, minmax(0, 1fr)); align-items: center; gap: 0; padding: 10px 5%; }
.phones .phone { width: 115%; aspect-ratio: 9 / 18.5; }
.phones .phone-1 { transform: rotate(-6deg) translateX(12%); z-index: 1; }
.phones .phone-2 { transform: translateY(-4%); z-index: 3; }
.phones .phone-3 { transform: rotate(6deg) translateX(-12%); z-index: 2; }
.comparison { grid-template-columns: 1fr 1fr; gap: 7%; padding: 8px 10%; }
.comparison .phone { width: 100%; aspect-ratio: 9 / 18.5; overflow: visible; }
.comparison .phone img { overflow: hidden; }
.comparison figcaption { position: absolute; left: 50%; top: -34px; translate: -50% 0; font-weight: 600; }
.comparison .compare-1 { transform: rotate(-4deg); }
.comparison .compare-2 { transform: rotate(4deg) translateY(3%); }
.monitor-scene { align-content: center; }
.monitor { width: 94%; aspect-ratio: 16 / 10; position: relative; z-index: 2; }
.monitor-neck { width: 11%; height: 48px; background: var(--ink); }
.monitor-foot { width: 40%; height: 12px; border-radius: 50%; background: var(--ink); }
.system-scene .browser-window { position: absolute; width: 78%; aspect-ratio: 16 / 10; }
.system-scene .system-1 { left: 0; top: 12%; transform: rotate(-3deg); }
.system-scene .system-2 { right: 0; bottom: 8%; transform: rotate(4deg); }
.device-scene.compact { min-height: 390px; }

.contact { background: var(--ink); color: var(--paper); padding: clamp(72px, 10vw, 150px) var(--pad); }
.contact > p { margin: 0 0 18px; }
.contact h2 { margin: 0; max-width: 16ch; font-family: var(--display); font-size: clamp(2.6rem, 6.3vw, 7rem); font-weight: 800; line-height: .97; letter-spacing: -.045em; }
.contact-links { margin-top: clamp(36px, 5vw, 68px); display: flex; flex-wrap: wrap; gap: 18px 42px; }
.contact-links a { min-height: 44px; display: inline-flex; align-items: center; color: var(--paper); text-underline-offset: 7px; text-decoration-color: var(--yellow); text-decoration-thickness: 3px; }
footer { display: flex; justify-content: space-between; padding: 22px var(--pad); background: var(--ink); color: var(--paper); border-top: 1px solid rgba(244,241,232,.25); font-size: .9rem; }

/* Case file */
.case-cover { padding: clamp(36px, 5vw, 72px) var(--pad) clamp(52px, 7vw, 96px); border-bottom: 3px solid var(--ink); }
.cover-red { background: var(--red); }
.cover-blue { background: var(--blue); color: white; }
.cover-green { background: var(--green); color: white; }
.cover-yellow { background: var(--yellow); }
.back-link { min-height: 44px; display: inline-flex; align-items: center; gap: 9px; font-weight: 600; text-underline-offset: 6px; }
.case-title { margin-top: clamp(44px, 6vw, 90px); display: grid; grid-template-columns: minmax(0, 1.2fr) minmax(260px, .8fr); gap: clamp(44px, 8vw, 130px); align-items: end; }
.case-title > * { min-width: 0; }
.case-title p { margin: 0; }
.case-title h1 { margin: 10px 0 0; font-family: var(--display); font-size: clamp(3rem, 5.3vw, 7rem); font-weight: 900; line-height: .88; letter-spacing: -.045em; text-wrap: balance; }
.case-title .case-short { margin-top: 22px; max-width: 34ch; font-size: clamp(1.25rem, 2vw, 1.7rem); line-height: 1.2; }
.case-title dl { margin: 0; border-top: 2px solid currentColor; }
.case-title dl div { display: grid; grid-template-columns: 110px 1fr; gap: 20px; padding: 15px 0; border-bottom: 1px solid currentColor; }
.case-title dt { opacity: .72; }
.case-title dd { margin: 0; font-weight: 600; }
.case-scope { margin-top: 24px; }
.case-scope > span { color: currentColor; opacity: .74; }
.cover-blue .case-scope li, .cover-green .case-scope li { background: rgba(255,255,255,.1); }
.case-hero { min-height: 78svh; padding: clamp(56px, 8vw, 120px) var(--pad); background: var(--paper-deep); display: grid; place-items: center; overflow: hidden; }
.case-hero .device-scene { width: min(1180px, 100%); min-height: min(66vw, 760px); }
.case-content { padding: clamp(72px, 10vw, 150px) var(--pad); }
.case-content blockquote { margin: 0; max-width: 23ch; font-family: var(--display); font-size: clamp(2rem, 4.4vw, 4.8rem); font-weight: 700; line-height: 1.04; letter-spacing: -.035em; }
.case-highlights { margin: clamp(72px, 10vw, 140px) 0 0 auto; max-width: 1050px; }
.case-highlights section { display: grid; grid-template-columns: minmax(0, 1fr); gap: clamp(22px, 4vw, 60px); padding: clamp(28px, 4vw, 52px) 0; border-top: 2px solid var(--ink); }
.case-highlights section:last-child { border-bottom: 2px solid var(--ink); }
.case-highlights h2 { margin: 0; font-family: var(--display); font-size: clamp(1.45rem, 2.7vw, 2.7rem); font-weight: 800; line-height: 1.05; letter-spacing: -.025em; }
.case-highlights p { margin: 14px 0 0; max-width: 55ch; font-size: clamp(1.08rem, 1.5vw, 1.25rem); }
.next-file { display: flex; justify-content: space-between; align-items: end; gap: 30px; padding: clamp(50px, 7vw, 100px) var(--pad); border-top: 3px solid var(--ink); text-decoration: none; }
.next-file span { font-size: 1.1rem; }
.next-file strong { font-family: var(--display); font-size: clamp(1.8rem, 4vw, 4.5rem); font-weight: 800; line-height: 1; }

.js .hero-copy > *, .js .cabinet { opacity: 0; animation: arrive 650ms cubic-bezier(.2,.8,.2,1) forwards; }
.js .hero-copy > p { animation-delay: 90ms; }
.js .hero-copy .hero-actions { animation-delay: 160ms; }
.js .cabinet { animation-delay: 120ms; }
@keyframes arrive { from { opacity: 0; transform: translateY(18px); } to { opacity: 1; transform: none; } }

@media (max-width: 980px) {
  .hero { grid-template-columns: 1fr; }
  .hero-copy { min-height: calc(70svh - var(--header)); }
  .cabinet { min-height: 68svh; border-left: 0; border-top: var(--border); }
  .project-preview { grid-template-columns: 1fr; }
  .preview-copy, .preview-head, .preview-body, .preview-foot { max-width: 700px; }
  
  .device-scene.compact { min-height: 500px; }
  .case-title { grid-template-columns: 1fr; }
}

@media (max-width: 720px) {
  :root { --header: 64px; }
  body { font-size: 16px; }
  .site-header nav { gap: 14px; }
  .site-header nav { gap: 12px; font-size: .95rem; }
  .hero-copy { min-height: calc(49svh - var(--header)); padding: 42px var(--pad) 36px; }
  .hero h1 { font-size: clamp(3.2rem, 18vw, 5.4rem); }
  .hero-copy > p { max-width: 15ch; font-size: clamp(1.65rem, 8vw, 2.5rem); }
  .cabinet { min-height: 54svh; padding: 20vw 7vw 12vw; }
  .cabinet-top { top: 10%; }
  .cabinet-tabs i { height: 42px; }
  .cabinet-tabs i:nth-child(1) { height: 32px; }
  .cabinet-tabs i:nth-child(2) { height: 48px; }
  .cabinet-tabs i:nth-child(3) { height: 38px; }
  .cabinet-tabs i:nth-child(4) { height: 54px; }
  .cabinet > p { display: none; }
  .experience { padding-inline: 14px; }
  .drawer { filter: drop-shadow(9px 12px 0 rgba(23,25,22,.16)); }
  /* ── Capability tabs on a phone ──────────────────────────────────────
     These are file tabs. A 2 x 2 grid of tall colour blocks is not a set of
     tabs, it is four buttons, and at 72-82px each it pushed the folder most
     of a screen down. So: one full-width tab per row, short enough to be a
     tab, and the drawer's own logic carried by colour — a closed folder
     shows only its coloured edge, the open one is filled. */
  .capability-tabs { grid-template-columns: 1fr; padding: 0; gap: 0; }
  .capability-tab {
    position: relative;
    min-height: 46px; padding: 11px 14px;
    flex-direction: row; align-items: center; justify-content: flex-start;
    transform: none; border: var(--border); border-radius: 8px 8px 0 0;
    background: var(--tab-tint); color: var(--ink);
    box-shadow: inset 8px 0 0 var(--tab-colour);
  }
  .capability-tab + .capability-tab { margin-top: -3px; }
  .capability-tab:nth-child(1) { z-index: 1; }
  .capability-tab:nth-child(2) { z-index: 2; }
  .capability-tab:nth-child(3) { z-index: 3; }
  .capability-tab:nth-child(4) { z-index: 4; }
  .capability-tab[aria-selected="true"] {
    min-height: 54px; transform: none; border-bottom: 0; border-radius: 8px 8px 0 0;
    background: var(--tab-colour); box-shadow: none;
  }
  .capability-tab[aria-selected="true"].tab-blue,
  .capability-tab[aria-selected="true"].tab-green { color: #fff; }
  .capability-tab:hover { transform: none; }
  .capability-tab span { font-size: .95rem; }
  .capability-tab small { font-size: .75rem; }
  .folder { min-height: 0; padding: 22px 18px 30px; }
  .folder::before { inset: 8px -8px -8px 8px; }
  
  
  
  .project-index { display: grid; gap: 8px; padding: 4px 0 12px; }
          .project-preview { gap: 34px; }
  .preview-copy h4, .preview-head h4 {
    font-size: clamp(2.4rem, 13vw, 4rem);
    overflow-wrap: anywhere;
  }
  .preview-media { order: 0; }
  .device-scene.compact { min-height: 330px; }
  .browser-scene .browser-window { width: 100%; }
  .phones { padding-inline: 2%; }
  .phone { border-width: 5px; border-radius: 22px; }
  .phone img { border-radius: 15px; }
  .comparison { padding-inline: 4%; }
  .contact h2 { font-size: clamp(2.5rem, 13vw, 4.1rem); }
  footer { display: grid; gap: 6px; }
  .case-title h1 { font-size: clamp(2.5rem, 10vw, 4rem); overflow-wrap: anywhere; }
  .case-title dl div { grid-template-columns: 90px 1fr; }
  .case-hero { min-height: 60svh; padding-inline: 12px; }
  .case-hero .device-scene { min-height: 390px; }
  .case-highlights section { grid-template-columns: minmax(0, 1fr); gap: 10px; }
  .next-file { display: grid; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation: none !important; transition: none !important; }
  .js .hero-copy > *, .js .cabinet { opacity: 1; }
}


/* ═══════════════════════════════════════════════════════════════════════
   Static-site additions. The prototype rendered everything from JS; this
   build ships real HTML, so picks are links and panels are hidden sections.
   ═══════════════════════════════════════════════════════════════════════ */

/* Project picks: links now, not buttons. Same visual contract. */

/* The .md nav link stays quiet until you look for it. */
.nav-md {
  font-family: var(--mono, ui-monospace, "SF Mono", Menlo, monospace);
  font-size: .82rem; letter-spacing: .02em; opacity: .62;
  text-decoration: none; border: 1.5px solid currentColor;
  border-radius: 4px; padding: 2px 6px; min-height: 0 !important;
}
.nav-md:hover, .nav-md:focus-visible { opacity: 1; }

/* About: the career shape the prototype was missing. */
.about {
  padding: clamp(64px, 9vw, 130px) clamp(20px, 5vw, 80px);
  display: grid; grid-template-columns: minmax(0, .34fr) minmax(0, 1fr);
  gap: clamp(28px, 5vw, 80px); border-bottom: var(--border);
}
.about h2 {
  margin: 0; font-family: var(--display); font-weight: 800;
  font-size: clamp(1.5rem, 2.6vw, 2.2rem); letter-spacing: -.03em; align-self: start;
}
.about-copy { max-width: 62ch; display: grid; gap: 1.1em; }
.about-copy p { margin: 0; font-size: clamp(1.02rem, 1.25vw, 1.2rem); line-height: 1.55; }
.about-tools { margin-top: clamp(20px, 3vw, 34px); padding-top: clamp(24px, 3vw, 34px); border-top: 1px solid color-mix(in srgb, var(--ink) 46%, transparent); }
.about-tools__intro { display: grid; gap: 7px; margin-bottom: clamp(18px, 2.4vw, 28px); }
.about-tools__intro h3 {
  margin: 0; max-width: 21ch; font-family: var(--display); font-weight: 800;
  font-size: clamp(1.5rem, 2.6vw, 2.2rem); line-height: 1.05; letter-spacing: -.03em;
}
.about-tools__intro p { max-width: 56ch; color: var(--muted); font-size: clamp(.94rem, 1.15vw, 1.05rem); line-height: 1.45; }
.about-tools__intro strong { color: var(--ink); font-weight: 700; }
.about-tools__tray {
  position: relative; isolation: isolate; padding: clamp(42px, 5vw, 58px) clamp(14px, 2.2vw, 28px) clamp(18px, 2.7vw, 32px);
  overflow: hidden; border: 3px solid var(--ink); border-radius: 12px;
  background-color: #202827;
  background-image:
    linear-gradient(rgba(255,255,255,.055) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255,255,255,.055) 1px, transparent 1px);
  background-size: 28px 28px;
  box-shadow: 9px 10px 0 var(--shadow);
}
.about-tools__tray::before,
.about-tools__tray::after {
  content: ""; position: absolute; z-index: 2; width: 8px; height: 8px;
  border: 1px solid rgba(21,25,24,.75); border-radius: 50%;
  background: #c7cdd0; box-shadow: inset 0 -2px 0 rgba(21,25,24,.28);
}
.about-tools__tray::before { top: 13px; right: 14px; }
.about-tools__tray::after { right: 14px; bottom: 13px; }
.about-tools__tray-label {
  position: absolute; z-index: 2; top: 13px; left: -7px; padding: 5px 14px 4px 18px;
  border: 2px solid var(--ink); background: var(--yellow); color: var(--ink);
  box-shadow: 3px 3px 0 rgba(0,0,0,.28); transform: rotate(-1.5deg);
  font-family: var(--mono); font-size: clamp(.59rem, 1vw, .7rem); font-weight: 800; letter-spacing: .1em;
}
.about-tools ul { position: relative; z-index: 1; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: clamp(15px, 2.5vw, 28px) clamp(8px, 1.6vw, 18px); margin: 0; padding: 0; list-style: none; }
.about-tools li {
  min-width: 0; min-height: clamp(82px, 12vw, 108px); padding: 8px 3px 4px;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 11px;
}
.about-tools__mark {
  width: clamp(40px, 5vw, 54px); height: clamp(40px, 5vw, 54px); display: grid; place-items: center;
  color: var(--tool-colour, #f3f5f7); filter: drop-shadow(0 4px 0 rgba(0,0,0,.2));
}
.about-tools svg, .about-tools img { display: block; width: 100%; height: 100%; object-fit: contain; }
.about-tools svg { fill: currentColor; }
.about-tools__name { color: #f3f5f7; font-family: var(--mono); font-size: clamp(.56rem, 1.3vw, .67rem); font-weight: 700; line-height: 1.1; letter-spacing: .075em; text-align: center; text-transform: uppercase; }
.about-tools__item--figma .figma-red { fill: #f24e1e; }
.about-tools__item--figma .figma-orange { fill: #ff7262; }
.about-tools__item--figma .figma-purple { fill: #a259ff; }
.about-tools__item--figma .figma-blue { fill: #1abcfe; }
.about-tools__item--figma .figma-green { fill: #0acf83; }
.about-tools__item--claude { --tool-colour: #d97757; }
.about-tools__item--meta { --tool-colour: #0467df; }
.about-tools__item--webflow { --tool-colour: #146ef5; }
.about-tools__item--vercel { --tool-colour: #f3f5f7; }
.about-tools__item--posthog { --tool-colour: #f54e00; }
.about-tools__item--stripe { --tool-colour: #635bff; }
.about-tools__item--ga4 .ga4-orange { fill: #e37400; }
.about-tools__item--ga4 .ga4-yellow { fill: #f9ab00; }
.about-tools__item--google-ads .gads-blue { fill: #4285f4; }
.about-tools__item--google-ads .gads-green { fill: #34a853; }
.about-tools__item--google-ads .gads-yellow { fill: #fbbc04; }
.about-tools__item--search-console { --tool-colour: #4285f4; }
.about-tools__item--dynamodb { --tool-colour: #8795ff; }
.about-tools__item--amazon-s3 { --tool-colour: #70b84c; }
@media (min-width: 721px) { .about-tools ul { grid-template-columns: repeat(5, minmax(0, 1fr)); } }
@media (prefers-reduced-motion: no-preference) {
  .js .about-tools.is-motion-ready .about-tools__item {
    opacity: 0; transform: translateY(14px) rotate(var(--tool-tilt, -2deg));
    transition: opacity 340ms cubic-bezier(.16,1,.3,1), transform 340ms cubic-bezier(.16,1,.3,1);
    transition-delay: calc(var(--tool-order) * 32ms);
  }
  .js .about-tools.is-motion-ready.is-visible .about-tools__item { opacity: 1; transform: translateY(0); }
}
/* Work with me: one door, stated plainly, before the contact block. */
.work-with-me {
  padding: clamp(52px, 7vw, 96px) clamp(20px, 5vw, 80px);
  display: grid; grid-template-columns: minmax(0, .34fr) minmax(0, 1fr);
  gap: clamp(28px, 5vw, 80px); align-items: start;
}
.work-with-me h2 {
  margin: 0; font-family: var(--display); font-weight: 800;
  font-size: clamp(1.5rem, 2.6vw, 2.2rem); letter-spacing: -.03em;
}
.work-with-me p { margin: 0; max-width: 60ch; font-size: clamp(1.08rem, 1.5vw, 1.36rem); line-height: 1.5; }

/* Ongoing-work signal. Absent entirely for one-off and parked projects. */
.shipped-signal {
  display: flex; align-items: center; gap: 9px; margin: 14px 0 0;
  font-size: .88rem; color: var(--muted);
}
.shipped-signal .dot {
  width: 8px; height: 8px; border-radius: 50%; background: #1f9d55;
  box-shadow: 0 0 0 3px rgba(31,157,85,.18); flex: 0 0 auto;
}
@media (prefers-reduced-motion: no-preference) {
  .shipped-signal .dot { animation: pulse 2.6s ease-in-out infinite; }
  @keyframes pulse {
    0%, 100% { box-shadow: 0 0 0 3px rgba(31,157,85,.18); }
    50%      { box-shadow: 0 0 0 6px rgba(31,157,85,.07); }
  }
}

.case-caps { margin: 18px 0 0; font-size: .88rem; color: var(--muted); }
.case-caps a { color: inherit; }

.footer-mid { opacity: .7; }
.footer-mid a { color: inherit; }

.page-404 { display: grid; place-items: center; min-height: 80vh; text-align: center; padding: 30px; }
.page-404 h1 { font-family: var(--display); font-size: clamp(2.4rem, 7vw, 4.4rem); font-weight: 900; letter-spacing: -.04em; margin: .2em 0; }
.page-404 .drawer-label { font-size: .78rem; letter-spacing: .14em; color: var(--muted); }

@media (max-width: 860px) {
  .about, .work-with-me { grid-template-columns: 1fr; }
}

/* [hidden] is a UA display:none, and any author display rule beats it.
   .folder and .project-preview both set display, so without this the drawer
   renders every panel at once. */
[hidden] { display: none !important; }

/* Board treatment. Most captures are designed explainer sheets that already
   carry their own headline and layout, so they get a clean edge and room to
   breathe rather than a device bezel around a thing that is not a device. */
.device-scene.boards { display: grid; gap: clamp(20px, 3vw, 40px); width: 100%; }
.board { margin: 0; }
.board img {
  display: block; width: 100%; height: auto;
  border: 2px solid var(--ink); border-radius: 4px; background: #fff;
  box-shadow: 10px 12px 0 rgba(23,25,22,.14);
}
.board figcaption {
  margin-top: 10px; font-size: .84rem; font-weight: 600;
  letter-spacing: .05em; text-transform: uppercase; color: var(--muted);
}
.case-hero .device-scene.boards { gap: clamp(34px, 5vw, 72px); }

.evidence-pending {
  display: grid; place-items: center; min-height: 240px; padding: 30px;
  border: 2px dashed rgba(23,25,22,.3); border-radius: 4px; color: var(--muted);
}
.evidence-pending p { margin: 0; }

/* Capability links sat dark-on-dark over the coloured cover. */
.case-caps { margin: 18px 0 0; font-size: .86rem; opacity: .85; }
.case-caps a { color: inherit; text-underline-offset: 3px; }
.cover-red .case-caps, .cover-blue .case-caps, .cover-green .case-caps { color: #fff; }
.cover-yellow .case-caps { color: var(--ink); }

/* Single-column highlights: the old gap value was a column gap and became a
   row gap when the 01/02/03 column came out. */
.case-highlights section { row-gap: 10px; }
.case-highlights section h2 { margin-bottom: 0; }

/* Photographer credit, shown wherever a supplied image carries one. */
.board figcaption .credit { display:block; margin-top:3px; text-transform:none; letter-spacing:0; font-weight:400; opacity:.75; }

/* A project may carry a case study, a live link, both or neither. */
.preview-actions { display: flex; flex-wrap: wrap; gap: 8px 26px; align-items: center; }
.preview-actions .text-link { margin-top: 0; }
.preview-actions .out { font-weight: 500; }

/* A parent project can carry one extra line of context under its description. */
.preview-note { margin: 10px 0 0; font-size: .92rem; color: var(--muted); max-width: 46ch; }

/* Two boards side by side where a card is making a two-sided claim. */
.preview-media .device-scene.boards:has(.board + .board) { grid-template-columns: 1fr 1fr; gap: 14px; }
.preview-media .device-scene.boards:has(.board + .board) figcaption { font-size: .7rem; }
@media (max-width: 860px) {
  .preview-media .device-scene.boards:has(.board + .board) { grid-template-columns: 1fr; }
}


/* ═══════════════════════════════════════════════════════════════════════
   Folder layout, 2026-09-21. The project list moved above the rule so the
   preview gets the full width, and the capability descriptions came out.
   ═══════════════════════════════════════════════════════════════════════ */
.folder-body { padding-top: clamp(28px, 3.5vw, 48px); }

/* Picks read as a row of file tabs rather than a sidebar. */

/* Full width for the evidence, now the sidebar has gone. */
.project-preview {
  display: grid; grid-template-columns: minmax(300px, .82fr) minmax(0, 1.18fr);
  gap: clamp(30px, 4.5vw, 70px); align-items: start; min-width: 0;
}
@media (max-width: 860px) {
  .project-preview { grid-template-columns: 1fr; }
}

/* ═══════════════════════════════════════════════════════════════════════
   One frame per image, 2026-09-21. A device mockup inside a white box
   inside a coloured folder is three frames for one piece of content.
   ═══════════════════════════════════════════════════════════════════════ */

/* plain — the image brings its own device or canvas. Nothing added. */
.device-scene.plainset { display: grid; gap: clamp(14px, 2vw, 26px); width: 100%; }
.device-scene.plainset:has(.plain + .plain) { grid-template-columns: 1fr 1fr; }
.plain { margin: 0; }
.plain img { width: 100%; height: auto; border: 0; border-radius: 0; background: none; box-shadow: none; }
.plain figcaption { margin-top: 8px; font-size: .78rem; font-weight: 600; letter-spacing: .06em; text-transform: uppercase; color: var(--muted); }

/* photo — a real photograph. A soft edge, no chrome pretending it is a screen. */
.device-scene.photoset { display: grid; gap: clamp(14px, 2vw, 26px); width: 100%; }
.device-scene.photoset:has(.photo + .photo) { grid-template-columns: 1fr 1fr; }
.photo { margin: 0; }
.photo img { width: 100%; height: auto; border-radius: 6px; box-shadow: 8px 10px 0 rgba(23,25,22,.13); }
.photo figcaption { margin-top: 8px; font-size: .78rem; color: var(--muted); }

@media (max-width: 860px) {
  .device-scene.plainset:has(.plain + .plain),
  .device-scene.photoset:has(.photo + .photo) { grid-template-columns: 1fr; }
}


@media (max-width: 860px) {
}


.folder[data-color="red"]    { --deep: #a8291c; }
.folder[data-color="blue"]   { --deep: #24378f; }
.folder[data-color="green"]  { --deep: #1a6444; }
.folder[data-color="yellow"] { --deep: #6b4e05; }

/* The row is the line. Tabs meet it; the selected one breaks through. */

@media (max-width: 860px) {
}


/* ═══════════════════════════════════════════════════════════════════════
   FOLDER TOPLINE — single definition. Replaced three competing blocks that
   were overriding each other, which is why the tabs would not sit down.

   The tabs are file tabs on the folder's own rule: they meet it, the
   selected one breaks it in the folder's colour, and the row casts a
   shadow so it reads as sitting in front.
   ═══════════════════════════════════════════════════════════════════════ */
.folder-topline {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: clamp(20px, 4vw, 56px); flex-wrap: wrap;
  border-bottom: 2px solid var(--ink);
}
.folder-topline h3 {
  flex: 0 1 auto; min-width: 0;
  margin: 0 0 18px; font-family: var(--display); font-weight: 800;
  font-size: clamp(1.6rem, 2.9vw, 2.9rem); letter-spacing: -.035em; line-height: 1;
}

.folder-topline .project-index {
  /* Never wrap the tab row itself: an orphaned tab on a second line is the
     same defect as an orphaned chip. If it will not fit beside the title,
     the whole row drops to its own full-width line instead. */
  display: flex; flex-wrap: nowrap; align-items: flex-end; gap: 4px;
  list-style: none; margin: 0 0 -2px; padding: 0;      /* -2px seats them on the rule */
  filter: drop-shadow(4px -3px 0 rgba(38,51,59,.16));   /* depth behind the row */
}
.folder-topline .project-index li { margin: 0; display: flex; }
.project-scroll-cue { display: none; }

.folder-topline .project-pick {
  display: flex; flex-direction: column; gap: 1px; justify-content: center;
  padding: 9px 15px 10px; min-height: 58px;
  border: 2px solid var(--ink); border-bottom: 2px solid var(--ink);
  border-radius: 9px 9px 0 0;
  background: var(--folder-fill); color: inherit; text-decoration: none;
  transition: background-color 150ms ease, color 150ms ease, padding 150ms ease;
}
/* A wrapping name made one tab taller than its neighbours. */
.folder-topline .project-pick span,
.folder-topline .project-pick small { white-space: nowrap; }
.folder-topline .project-pick span { font-weight: 700; font-size: .93rem; line-height: 1.15; }
.folder-topline .project-pick small { font-size: .78rem; color: var(--muted); line-height: 1.15; }
.folder-topline .project-pick:hover { background: rgba(255,255,255,.62); }

/* Selected: the folder's OWN colour, matching its capability tab exactly,
   and its bottom edge matches so it breaks through the rule. */
.folder-topline .project-pick[aria-current="true"] { position: relative; z-index: 1; }
.folder[data-color="red"]    .project-pick[aria-current="true"] { background: var(--red);    color: var(--ink); border-bottom-color: var(--red); }
.folder[data-color="blue"]   .project-pick[aria-current="true"] { background: var(--blue);   color: #fff;       border-bottom-color: var(--blue); }
.folder[data-color="green"]  .project-pick[aria-current="true"] { background: var(--green);  color: #fff;       border-bottom-color: var(--green); }
.folder[data-color="yellow"] .project-pick[aria-current="true"] { background: var(--yellow); color: var(--ink); border-bottom-color: var(--yellow); }
.folder[data-color="red"]    .project-pick[aria-current="true"] small,
.folder[data-color="yellow"] .project-pick[aria-current="true"] small { color: rgba(21,25,24,.72); }
.folder[data-color="blue"]   .project-pick[aria-current="true"] small,
.folder[data-color="green"]  .project-pick[aria-current="true"] small { color: rgba(255,255,255,.78); }

@media (max-width: 860px) {
  /* Project tabs are one physical row peeking over the open folder. Every tab
     remains visible; equal heights stop the active one looking heavier. */
  .folder-topline { flex-direction: column; align-items: stretch; gap: 12px; padding-bottom: 0; }
  .folder-topline h3 { margin-bottom: 0; }
  .folder-topline .project-index {
    display: flex; flex-wrap: nowrap; align-items: stretch; gap: 3px;
    min-width: 0; max-width: 100%; overflow: visible;
    margin: 0 0 -2px; padding: 0 0 2px; filter: none;
    -webkit-mask-image: none !important; mask-image: none !important;
  }
  .folder-topline .project-index li { flex: 1 1 0; min-width: 0; }
  .folder-topline .project-pick {
    width: 100%; height: 58px; min-height: 58px; padding: 7px 4px 9px;
    border-radius: 7px 7px 0 0; border-bottom-width: 2px;
  }
  .folder-topline .project-pick span {
    display: -webkit-box; overflow: hidden; white-space: normal;
    -webkit-box-orient: vertical; -webkit-line-clamp: 2;
    font-size: clamp(.64rem, 2.9vw, .78rem); line-height: 1.06;
    overflow-wrap: anywhere;
  }
  .folder-topline .project-pick small { display: none; }
}


/* ═══════════════════════════════════════════════════════════════════════
   OPEN DRAWER PROJECT SNAPSHOTS

   The filing system is shared; the editorial hierarchy belongs to the work.
   Presentation classes change the whole reading path, not just the crop.
   Projects without a headline keep the original preview above.
   ═══════════════════════════════════════════════════════════════════════ */

/* Wide snapshots use named regions so the same semantic order can take on
   different silhouettes without duplicating copy or evidence. */
@media (min-width: 981px) {
  .project-preview.is-snapshot {
    grid-template-columns: minmax(270px, .78fr) minmax(0, 1.22fr);
    grid-template-rows: auto auto 1fr;
    grid-template-areas: "head media" "body media" "foot media";
    column-gap: clamp(30px, 4.5vw, 70px);
    row-gap: 0;
    align-items: start;
  }
  .is-snapshot .preview-head > :last-child { margin-bottom: 0; }
  .is-snapshot .preview-head  { grid-area: head; min-width: 0; }
  .is-snapshot .preview-media { grid-area: media; min-width: 0; }
  .is-snapshot .preview-body  { grid-area: body; min-width: 0; }
  .is-snapshot .preview-foot  { grid-area: foot; min-width: 0; }

  /* A rights-held proof is absent from the public build, not replaced by a
     blank media column or a review-state placeholder. */
  .project-preview.is-snapshot.has-no-media {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto auto auto;
    grid-template-areas: "head" "body" "foot";
    row-gap: clamp(24px, 3vw, 40px);
  }
  .is-snapshot.has-no-media .preview-head { max-width: 1100px; }
  .is-snapshot.has-no-media .preview-short { max-width: 65ch; }
  .is-snapshot.has-no-media .preview-body { max-width: 900px; }

  /* Product and physical stories let the artefact enter first. */
  .is-snapshot.layout-image,
  .is-snapshot.layout-photo,
  .is-snapshot.layout-moment {
    grid-template-columns: minmax(0, 1.28fr) minmax(280px, .72fr);
    grid-template-areas: "media head" "media body" "media foot";
  }

  /* A measured change reads headline → numbers → proof. */
  .is-snapshot.layout-numbers {
    grid-template-columns: minmax(280px, .68fr) minmax(0, 1.32fr);
    grid-template-rows: auto auto 1fr;
    grid-template-areas: "head head" "body media" "foot media";
    row-gap: clamp(26px, 3.2vw, 42px);
  }
  .layout-numbers .preview-head { max-width: 1040px; }

  /* Comparisons and motion need room to be read, not squeezed into a sidecar. */
  .is-snapshot.layout-comparison,
  .is-snapshot.layout-motion {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto auto auto auto;
    grid-template-areas: "head" "media" "body" "foot";
    row-gap: clamp(26px, 3.3vw, 46px);
  }
  .layout-comparison .preview-head,
  .layout-motion .preview-head { max-width: 1040px; }
  .layout-comparison .preview-body,
  .layout-motion .preview-body { max-width: 1180px; }

  /* Method stories give the argument more room than the diagram. */
  .is-snapshot.layout-copy {
    grid-template-columns: minmax(0, 1.2fr) minmax(300px, .8fr);
    grid-template-areas: "head media" "body media" "foot media";
  }
}

.is-snapshot .preview-head h4 { font-size: clamp(2rem, 3vw, 3.35rem); }
.layout-comparison .preview-head h4,
.layout-motion .preview-head h4,
.layout-copy .preview-head h4 { font-size: clamp(2.35rem, 4.2vw, 4.75rem); max-width: 18ch; }
.is-snapshot .preview-short {
  margin: 26px 0 0; max-width: 61ch;
  font-size: clamp(1.06rem, 1.5vw, 1.28rem); line-height: 1.38;
}
.is-snapshot .preview-short + .preview-short { margin-top: 14px; }
.layout-image .preview-short,
.layout-photo .preview-short,
.layout-moment .preview-short { max-width: 40ch; }
.snapshot-quote {
  margin: clamp(28px, 4vw, 52px) 0 0; max-width: 18ch;
  padding-top: clamp(18px, 2vw, 26px); border-top: 2px solid var(--ink);
  font-family: var(--display); font-weight: 800;
  font-size: clamp(1.45rem, 2.7vw, 2.5rem); line-height: 1.02; letter-spacing: -.025em;
}

/* Ownership. Same label grammar as "What I worked on", one rung up the page,
   because who owned what is the question the rest of the card cannot answer. */
.project-ownership { margin-top: 28px; padding-top: 18px; border-top: 1px solid var(--ink); }
.project-ownership > span {
  display: block; margin-bottom: 9px;
  color: var(--muted); font-size: .88rem; font-weight: 700;
}
.project-ownership p { margin: 0; max-width: 48ch; font-size: .98rem; line-height: 1.45; }

/* A recruiter's quick-scan layer, but not a strip of generic skill pills.
   Each contribution is a small ledger row in the same filing-system language
   as the rest of the drawer. */
.is-snapshot .project-scope ul {
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 0 18px;
  counter-reset: contribution;
}
.is-snapshot .project-scope li {
  counter-increment: contribution;
  display: grid; grid-template-columns: 1.7rem minmax(0, 1fr); gap: 7px;
  align-items: baseline; padding: 8px 0 7px;
  border: 0; border-top: 1px solid rgba(21, 25, 24, .28);
  border-radius: 0; background: transparent;
  font-weight: 600; line-height: 1.18;
}
.is-snapshot .project-scope li::before {
  content: counter(contribution, decimal-leading-zero);
  font-size: .65rem; font-weight: 700; letter-spacing: .06em; color: var(--muted);
}
.is-snapshot .project-scope li:nth-child(odd):last-child { grid-column: auto; }
.is-snapshot .project-scope--lead { margin-top: clamp(26px, 3vw, 42px); }
.is-snapshot .project-scope--lead ul { gap: 0 clamp(18px, 3vw, 42px); }
.is-snapshot .project-scope--lead li {
  min-height: 70px; align-items: center; padding: 16px 0 14px;
  font-family: var(--display); font-size: clamp(1.08rem, 1.8vw, 1.45rem); font-weight: 800;
}

/* Result. The introduction sits on the same rule the old result block used,
   so the card's vertical rhythm is unchanged. */
.result-intro { margin-top: 26px; padding-top: 18px; border-top: 1px solid var(--ink); }
.result-kicker { margin: 0 0 5px; color: var(--muted); font-size: .88rem; font-weight: 700; }
.result-line {
  margin: 0; font-family: var(--display); font-weight: 700;
  font-size: clamp(1.1rem, 1.55vw, 1.32rem); line-height: 1.14; letter-spacing: -.025em;
  max-width: 30ch;
}

/* Metrics are evidence, not widgets: typographic rows, each on a hairline.
   Rows compose identically at one, two or three, so none of them leaves a
   half-filled grid the way a columns layout would. */
.metric-group { margin-top: 22px; display: grid; }
.metric { padding: 13px 0; border-top: 1px solid rgba(21, 25, 24, .22); }
.metric:first-child { border-top: 0; padding-top: 6px; }
.metric:last-child { padding-bottom: 0; }
.metric-value {
  margin: 0; display: flex; align-items: baseline; flex-wrap: wrap; gap: 4px 12px;
  font-family: var(--display); font-weight: 800;
  font-size: clamp(1.55rem, 2.3vw, 2.05rem); line-height: 1; letter-spacing: -.035em;
}
/* A supporting calculation, not a second number. */
.metric-aside { font-size: .56em; font-weight: 700; letter-spacing: -.015em; color: var(--muted); }
.metric-label { margin: 7px 0 0; font-size: .95rem; font-weight: 700; line-height: 1.2; }
.metric-note { margin: 3px 0 0; max-width: 46ch; font-size: .85rem; line-height: 1.3; color: var(--muted); }
/* A condition that must travel with the number without interrupting it. */
.metric-source { margin: 7px 0 0; max-width: 46ch; font-size: .77rem; line-height: 1.32; color: var(--muted); }

.metric-group.is-inline {
  grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
  border-top: 2px solid var(--ink); border-bottom: 1px solid rgba(21, 25, 24, .28);
}
.metric-group.is-inline .metric { border: 0; padding: 14px 16px 16px 0; }
.metric-group.is-inline .metric + .metric { padding-left: 16px; border-left: 1px solid rgba(21, 25, 24, .28); }
.metric-group.is-inline .metric-value { font-size: clamp(1.45rem, 2.2vw, 2.1rem); }

.metric-group.is-hero { margin-top: 0; gap: clamp(22px, 3vw, 38px); }
.metric-group.is-hero .metric { padding: 18px 0; border-top: 2px solid var(--ink); }
.metric-group.is-hero .metric-value {
  display: block; font-size: clamp(2.6rem, 5.2vw, 4.8rem); line-height: .86;
  font-variant-numeric: tabular-nums;
}
.metric-group.is-hero .metric-label { margin-top: 13px; font-size: 1rem; }

/* ── EVIDENCE COMPOSITIONS ─────────────────────────────────────────────
   Three arrangements, shared by every snapshot. A per-asset `aspect` and
   `focal` arrive as custom properties, so a crop is data, not a new rule.
   Nothing here is offset, rotated or overlapped in a way that carries
   meaning: the labels carry it, and they are real text. */
.evidence { position: relative; width: 100%; min-width: 0; }

/* project-desktop — the Eulogize overview is a contents page for the breadth
   of the role. One desktop plane replaces the old expansion infographic; the
   folders themselves are the navigation and take their colour from the same
   capability tabs they open. It is deliberately a little loose rather than a
   row of equal cards, but the labels remain ordinary text and real links. */
.evidence-project-desktop {
  min-height: clamp(390px, 37vw, 520px);
  overflow: hidden;
  border: 3px solid var(--ink);
  background:
    radial-gradient(circle at 78% 24%, rgba(255,255,255,.56), transparent 31%),
    linear-gradient(145deg, #e7ecec 0%, #d7dedf 100%);
  box-shadow: 14px 16px 0 rgba(38, 51, 59, .18);
}
.project-desktop-bar {
  min-height: 38px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
  padding: 8px 12px 7px;
  border-bottom: 2px solid var(--ink);
  background: rgba(255,255,255,.72);
  font-size: .7rem;
  font-weight: 800;
  letter-spacing: .07em;
  line-height: 1;
  text-transform: uppercase;
}
.project-desktop-bar span:last-child { color: var(--muted); }
.project-desktop-files {
  min-height: clamp(350px, 34vw, 480px);
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  align-content: center;
  align-items: start;
  gap: clamp(34px, 4vw, 58px) clamp(18px, 2vw, 30px);
  padding: clamp(38px, 5vw, 72px) clamp(22px, 3.3vw, 48px);
}
.project-desktop-file {
  --file-accent: var(--red);
  --file-fill: #ffdcd7;
  min-width: 0;
  display: grid;
  justify-items: center;
  align-content: start;
  color: var(--ink);
  text-align: center;
  text-decoration: none;
}
.project-desktop-file.file-blue { --file-accent: var(--blue); --file-fill: #dfe6ff; }
.project-desktop-file.file-green { --file-accent: var(--green); --file-fill: #d9f0e3; }
.project-desktop-file.file-yellow { --file-accent: var(--yellow); --file-fill: #fff0b8; }
.project-desktop-file:nth-child(2) { margin-top: 25px; }
.project-desktop-file:nth-child(4) { margin: 4px 0 0 24px; }
.project-desktop-file:nth-child(5) { margin-top: -8px; }
.project-file-folder {
  position: relative;
  width: clamp(88px, 9vw, 122px);
  aspect-ratio: 1.42;
  margin: 12px 0 15px;
  border: 2px solid var(--ink);
  border-radius: 3px 3px 6px 6px;
  background: var(--file-fill);
  box-shadow: 7px 8px 0 rgba(38,51,59,.18);
  transform-origin: 50% 100%;
  transition: transform 160ms ease, box-shadow 160ms ease;
}
.project-file-folder::before {
  content: "";
  position: absolute;
  left: -2px;
  top: -14px;
  width: 47%;
  height: 15px;
  border: 2px solid var(--ink);
  border-bottom: 0;
  border-radius: 5px 5px 0 0;
  background: var(--file-accent);
}
.project-file-folder span {
  position: absolute;
  left: 10%;
  right: 10%;
  top: 28%;
  height: 2px;
  background: rgba(21,25,24,.3);
  box-shadow: 0 10px 0 rgba(21,25,24,.2);
}
.project-file-name {
  max-width: 18ch;
  font-family: var(--display);
  font-size: clamp(.96rem, 1.2vw, 1.1rem);
  font-weight: 800;
  line-height: 1.05;
  text-wrap: balance;
}
.project-desktop-file small {
  margin-top: 5px;
  color: var(--muted);
  font-size: .72rem;
  font-weight: 700;
  line-height: 1.15;
}
.project-desktop-file:hover .project-file-folder,
.project-desktop-file:focus-visible .project-file-folder {
  transform: translateY(-5px) rotate(-1.5deg);
  box-shadow: 10px 12px 0 rgba(38,51,59,.2);
}
.project-desktop-file:hover .project-file-name {
  text-decoration: underline;
  text-decoration-thickness: 2px;
  text-underline-offset: 3px;
}
.project-desktop-file:focus-visible { outline: 3px solid var(--ink); outline-offset: 8px; }

/* A lead/support group is a REAL box, which is what lets the mobile rule move
   it. The two compositions that overlap their frames dissolve theirs on
   desktop, so every absolute-positioning rule below still addresses .ev-frame
   as a direct child of .evidence and none of them had to change. */
.ev-group { display: grid; gap: clamp(12px, 1.6vw, 18px); min-width: 0; }
.evidence-progression .ev-group,
.evidence-hero-inset .ev-group { display: contents; }
/* evidence-set — the lead sits OUTSIDE the support's frame. The authored lead
   is already a designed sheet with its own edge, and a white box around a
   board inside a coloured folder is three frames for one piece of content. */
.evidence-set { display: grid; gap: clamp(16px, 2.2vw, 26px); }

/* comparison-proof — a current/proposed pair where neither state is allowed
   to dominate or masquerade as a shipped before/after. The third frame is the
   diagnosis beneath them, so the composition reads product → decision → proof. */
.evidence-comparison .ev-compare-pair {
  grid-template-columns: repeat(2, minmax(0, 1fr));
  align-items: start;
}
.evidence-comparison .ev-group-support {
  padding: clamp(12px, 1.6vw, 18px);
  border: 3px solid var(--ink); background: rgba(255, 255, 255, .45);
  box-shadow: 14px 16px 0 rgba(38, 51, 59, .18);
}
.evidence-comparison figcaption { bottom: 0; }

/* search-share — the landscape result and portrait artefact are one cause and
   effect unit. The search owns the width it needs for its map; the card stays
   recognisably 4:5 instead of being stretched into an equal screenshot tile. */
.evidence-search-share .ev-search-share-pair {
  grid-template-columns: minmax(0, 1.55fr) minmax(190px, .72fr);
  align-items: start;
}
.evidence-search-share .ev-group-support {
  padding: clamp(12px, 1.6vw, 18px);
  border: 3px solid var(--ink); background: rgba(255, 255, 255, .45);
  box-shadow: 14px 16px 0 rgba(38, 51, 59, .18);
}
.evidence-search-share figcaption { bottom: 0; }

.ev-frame { margin: 0; position: relative; }
.ev-frame img,
.ev-frame video {
  display: block; width: 100%; height: auto;
  aspect-ratio: var(--ar, auto); object-fit: cover;
  border: 2px solid var(--ink); background: #fff;
}
/* An evidence label belongs to its frame, so it sits on the frame's edge and
   is ordinary text for every reader. */
.ev-frame figcaption {
  position: absolute; left: 0; z-index: 3;
  padding: 5px 10px 4px;
  background: var(--ink); color: var(--paper);
  font-size: .68rem; font-weight: 700; letter-spacing: .055em; line-height: 1.1;
  white-space: nowrap;
}

/* desktop-pair — the onboarding story only needs one moment before and after
   the first details are entered. Two equal desktop monitors keep the product
   context legible without turning the evidence area into another card grid. */
.evidence-desktop-pair { padding: 8px 0 42px; }
.evidence-desktop-pair .ev-group-lead {
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(16px, 2.1vw, 28px);
  align-items: start;
}
.ev-desktop-monitor { min-width: 0; margin: 0; }
.desktop-monitor-shell {
  position: relative;
  padding: clamp(7px, .8vw, 10px) clamp(7px, .8vw, 10px) clamp(20px, 2vw, 27px);
  border: 2px solid var(--ink);
  border-radius: 11px 11px 7px 7px;
  background: linear-gradient(180deg, #f7f8f7 0%, #d7dcdb 100%);
  box-shadow: 0 18px 30px rgba(38, 51, 59, .18);
}
.desktop-monitor-screen {
  overflow: hidden;
  border: 1px solid rgba(21,25,24,.7);
  border-radius: 5px 5px 2px 2px;
  background: #fff;
}
.desktop-monitor-screen img,
.desktop-monitor-screen video {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 3 / 2;
  object-fit: cover;
  border: 0;
}
.desktop-monitor-stand {
  position: absolute;
  top: calc(100% + 2px);
  left: 50%;
  width: 25%;
  height: 24px;
  translate: -50% 0;
  border: 2px solid var(--ink);
  border-top: 0;
  background: linear-gradient(90deg, #cbd0cf, #f4f5f4 48%, #c4cac9);
}
.desktop-monitor-stand::after {
  content: "";
  position: absolute;
  left: 50%;
  bottom: -7px;
  width: 150%;
  height: 7px;
  translate: -50% 0;
  border: 2px solid var(--ink);
  border-radius: 7px 7px 3px 3px;
  background: #d7dcdb;
}
.ev-desktop-monitor figcaption {
  margin-top: 39px;
  color: var(--ink);
  font-size: .78rem;
  font-weight: 800;
  line-height: 1.15;
  text-align: center;
}

/* desktop-phone — one compact product proof for the shared left/right snapshot
   chassis. The desktop comparison owns the width; the phone makes the live
   directory recognisable without sending either screen below the copy. */
.evidence-desktop-phone {
  min-height: clamp(430px, 39vw, 540px);
}
.evidence-desktop-phone .ev-group-lead,
.evidence-desktop-phone .ev-group-support {
  position: absolute;
  display: block;
}
.evidence-desktop-phone .ev-group-lead {
  top: 7%; right: 0; width: 82%; z-index: 1;
}
.evidence-desktop-phone .ev-group-support {
  left: 0; bottom: 0; width: 29%; z-index: 3;
}
.evidence-desktop-phone .ev-product-monitor { width: 100%; }
.evidence-desktop-phone .desktop-monitor-screen img {
  aspect-ratio: 3 / 2;
  object-fit: cover;
  object-position: center top;
}
.evidence-desktop-phone .ev-product-phone {
  width: 100%;
  aspect-ratio: 9 / 18.5;
  rotate: -2deg;
}
.evidence-desktop-phone .ev-product-phone img {
  width: 100%; height: 100%;
  object-fit: cover; object-position: center top;
}

/* mobile-share — the search is a phone product and the share card is its
   social payoff. They stay one composition: product on the left, something
   worth dropping into the group chat on the right. */
.evidence-mobile-share {
  min-height: clamp(430px, 42vw, 570px);
}
.evidence-mobile-share .ev-group-lead,
.evidence-mobile-share .ev-group-support {
  position: absolute;
  display: block;
}
.evidence-mobile-share .ev-group-lead {
  left: 1%; bottom: 0; width: 36%; z-index: 2;
}
.evidence-mobile-share .ev-group-support {
  right: 0; top: 4%; width: 62%; z-index: 1;
}
.evidence-mobile-share .ev-golf-search-phone {
  width: 100%; aspect-ratio: 9 / 18.5; rotate: -2deg;
}
.evidence-mobile-share .ev-golf-search-phone img {
  width: 100%; height: 100%; object-fit: cover; object-position: center top;
}
.evidence-mobile-share .ev-golf-share-card {
  margin: 0; rotate: 2deg;
  filter: drop-shadow(13px 15px 0 rgba(38,51,59,.20));
}
.evidence-mobile-share .ev-golf-share-card img {
  display: block; width: 100%; height: auto;
  border: 2px solid var(--ink); background: #fff;
}

/* progression — two filled states, read 01 then 02, with 02 dominant.
   The vertical offset is what keeps step 1's own step marker and question
   visible above step 2's top edge; without it the front frame buries them. */
/* The two widths and the container ratio are one calculation, not three taste
   choices. At 3:2 sources, 72% and 90% put step 2's top edge at 28% of the
   container, which clears step 1's step marker (31% of its own height) and its
   question (38%). Change any one of them and re-check those two rows: that is
   the whole point of the composition. */
.evidence-progression { aspect-ratio: 25 / 22; margin: 14px 0 16px; }
.evidence-progression .ev-frame { position: absolute; }
.evidence-progression .ev-behind { top: 0; left: 0; width: 72%; z-index: 1; rotate: -1.1deg; }
.evidence-progression .ev-front {
  right: 0; bottom: 0; width: 90%; z-index: 2; rotate: .9deg;
  box-shadow: 14px 16px 0 rgba(38, 51, 59, .20);
}
.evidence-progression .ev-behind figcaption { top: 0; translate: 0 -50%; }
.evidence-progression .ev-front figcaption { bottom: 0; translate: 0 50%; }

/* evidence-stack — one outer frame, three images that keep their own edges.
   The lead reads as a deliberate state system; the pair beneath is the
   design-to-production claim, so neither half may be dropped. */
.evidence-stack {
  display: grid; gap: clamp(12px, 1.6vw, 18px);
  padding: clamp(12px, 1.6vw, 18px);
  border: 3px solid var(--ink); background: rgba(255, 255, 255, .45);
  box-shadow: 14px 16px 0 rgba(38, 51, 59, .18);
}
.evidence-stack .ev-pair { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(12px, 1.6vw, 18px); }
.evidence-stack .ev-pair:has(> :only-child) { grid-template-columns: 1fr; }
.evidence-stack figcaption { bottom: 0; }

/* system-collage — the same outer frame, with a mosaic where the single lead
   image was. Multi-column rather than justified rows: these captures range
   from 0.37 to 4.16 in aspect, and in a justified row one tall tile squashes
   everything beside it. Columns let a tall tile simply own more of its
   column, which is also what makes the mosaic read as a collage rather than
   a grid. */
.evidence-system .ev-mosaic { columns: 3; column-gap: clamp(8px, 1.1vw, 12px); }
.evidence-system .ev-tile { break-inside: avoid; margin: 0 0 clamp(8px, 1.1vw, 12px); }
/* Tiles carry the crop's own measured ratio, from 0.65 to 8.67, and a
   lighter edge than the pair below: at this size a 2px border competes with
   the control inside it. */
.evidence-system .ev-tile img,
.evidence-system .ev-tile video { border-width: 1px; aspect-ratio: var(--ar); }
/* The first tile leads full width. It is the one capture that shows the
   system inside a real product surface, and at column width its status and
   controls collapse to about 50px and stop being readable. */
.evidence-system .ev-tile:first-child { column-span: all; margin-bottom: clamp(8px, 1.1vw, 12px); }
/* One label for the whole mosaic, sat in its last column so it reads as
   belonging to the group rather than to whichever tile it lands beside. */
.evidence-system .ev-mosaic-label {
  break-inside: avoid; margin: 0;
  padding: 5px 10px 4px; background: var(--ink); color: var(--paper);
  font-size: .68rem; font-weight: 700; letter-spacing: .055em; line-height: 1.1;
  width: max-content; max-width: 100%;
  column-span: all;   /* the label belongs to the mosaic, not to one column */
}

/* hero-inset — one dominant proof, one supporting detail over its lower
   right. The inset hangs below the lead, never past its right edge, so it
   cannot introduce horizontal overflow.

   The hang is 15%, not a token amount, because the lead here is a designed
   board whose lower right carries readable sentences. At 6% the inset landed
   across the middle of them and read as a rendering fault rather than a
   deliberate overlap. If a future lead is a photograph, a smaller hang is
   fine; check what the corner actually contains before reducing it. */
.evidence-hero-inset { padding-bottom: 15%; }
.evidence-hero-inset .ev-lead { width: 100%; }
.evidence-hero-inset .ev-lead figcaption { bottom: 0; }
.evidence-hero-inset .ev-inset {
  position: absolute; right: 0; bottom: 0; width: 38%; z-index: 2;
  box-shadow: 12px 14px 0 rgba(38, 51, 59, .22);
}
.evidence-hero-inset .ev-inset figcaption { bottom: 0; font-size: .62rem; }

/* browser-sections — two real slices of one live website. The wide hero
   establishes the page; the animated workflow section overlaps it like a
   second browser window, without interrupting the copy column. */
.evidence-browser-sections {
  position: relative;
  min-height: clamp(430px, 40vw, 565px);
}
.evidence-browser-sections .ev-group { display: contents; }
.ev-browser-section {
  overflow: hidden;
  margin: 0;
  border: 2px solid var(--ink);
  border-radius: 8px;
  background: #fff;
  box-shadow: 12px 14px 0 rgba(38, 51, 59, .18);
}
.ev-browser-bar {
  display: flex;
  align-items: center;
  gap: 6px;
  height: 26px;
  padding: 0 9px;
  border-bottom: 1px solid rgba(21, 25, 24, .55);
  background: #e7e5df;
}
.ev-browser-bar i {
  flex: 0 0 auto;
  width: 8px;
  height: 8px;
  border: 1px solid var(--ink);
  border-radius: 50%;
}
.ev-browser-bar span {
  min-width: 0;
  margin-left: 4px;
  overflow: hidden;
  color: var(--muted);
  font-size: .58rem;
  font-weight: 700;
  line-height: 1;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.ev-browser-screen img,
.ev-browser-screen video {
  display: block;
  width: 100%;
  height: auto;
}
.ev-browser-hero { width: 100%; }
.ev-browser-motion {
  position: absolute;
  right: 0;
  bottom: 0;
  z-index: 2;
  width: 68%;
  rotate: 1deg;
}

/* browser-motion-sequence — four approved motion clips read as one product
   story, followed by the finished page and its delivery stack. */
.evidence-browser-motion { display: grid; gap: clamp(18px, 2.4vw, 28px); }
.evidence-browser-motion .ev-motion-sequence { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 8px; }
.ev-motion-step { position: relative; min-width: 0; margin: 0; border: 2px solid var(--ink); background: #fff; box-shadow: 7px 8px 0 rgba(38,51,59,.16); }
.ev-motion-step::after { content: ""; position: absolute; top: 50%; right: -9px; z-index: 3; width: 16px; border-top: 2px solid var(--ink); }
.ev-motion-step:last-child::after { display: none; }
.ev-motion-number { position: absolute; left: 6px; top: 6px; z-index: 3; padding: 3px 5px 2px; background: var(--ink); color: var(--paper); font: 700 .56rem var(--mono); }
.ev-motion-screen { position: relative; overflow: hidden; aspect-ratio: 1; background: var(--paper-deep); }
.ev-motion-screen video, .ev-motion-screen img { display: block; width: 100%; height: 100%; object-fit: cover; }
.ev-motion-step figcaption, .ev-motion-page figcaption { position: static; display: block; padding: 6px 7px 5px; background: var(--ink); color: var(--paper); font-size: .56rem; white-space: normal; }
.evidence-browser-motion .ev-group-support { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: end; gap: 12px; }
.ev-motion-page { overflow: hidden; margin: 0; border: 2px solid var(--ink); border-radius: 8px; background: #fff; box-shadow: 10px 12px 0 rgba(38,51,59,.16); }
.ev-motion-page img { display: block; width: 100%; }
.ev-tool-strip { display: grid; border: 2px solid var(--ink); background: #fff; }
.ev-tool-strip span { padding: 7px 9px 6px; border-top: var(--hairline); font: 700 .55rem var(--mono); letter-spacing: .04em; }
.ev-tool-strip span:first-child { border-top: 0; }

/* phone-fan — the mobile product views are the lead artefact;
   the system diagrams sit behind them as supporting evidence. */
.evidence-phone-fan { display: grid; gap: clamp(20px, 2.8vw, 34px); }
.evidence-phone-fan .phones { min-height: clamp(430px, 47vw, 680px); }
.evidence-phone-fan .phone { margin: 0; }
.evidence-phone-fan .phone img { aspect-ratio: auto; height: 100%; object-fit: cover; object-position: top; }
.evidence-phone-fan .ev-group-support { grid-template-columns: repeat(2, minmax(0, 1fr)); }

/* photo-story — one lived moment, then the designed artefacts that made the
   moment possible. The support pair hangs off the lower edge like ephemera. */
.evidence-photo-story { display: grid; padding-bottom: 8%; }
.evidence-photo-story .ev-photo-lead img { width: 100%; aspect-ratio: var(--ar, 16 / 10); }
.evidence-photo-story .ev-group-support {
  position: relative; z-index: 2; width: 48%; margin: -16% 2% 0 auto;
  grid-template-columns: minmax(0, 1.25fr) minmax(110px, .75fr); align-items: end;
  padding: clamp(10px, 1.3vw, 16px); border: 3px solid var(--ink);
  background: rgba(255,255,255,.88); box-shadow: 14px 16px 0 rgba(38, 51, 59, .2);
}
.evidence-photo-story .ev-group-support:has(> :only-child) {
  width: 34%; grid-template-columns: 1fr;
}
.evidence-photo-story .ev-photo-support img { width: 100%; aspect-ratio: var(--ar, auto); }
.evidence-photo-story figcaption { bottom: 0; max-width: 100%; white-space: normal; }
.ev-frame figcaption .credit { display: block; margin-top: 3px; color: rgba(243,245,247,.72); font-size: .88em; font-weight: 500; letter-spacing: .02em; text-transform: none; }

/* instant-prints — four small convention snapshots. They form an overview,
   not an overlapping hero where one photograph has to carry the project. */
.evidence-instant-prints { display: grid; min-height: 0; padding: 10px 0 16px; }
.evidence-instant-prints .ev-group-lead {
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));
  align-items: end; gap: clamp(10px, 1.4vw, 18px); width: 100%; min-height: 0;
}
.evidence-instant-prints .ev-instant {
  position: relative; width: auto; margin: 0; padding: 8px 8px 0;
  border: 2px solid var(--ink); background: #fff;
  box-shadow: 7px 8px 0 rgba(38,51,59,.16);
}
.evidence-instant-prints .ev-instant img { display: block; width: 100%; aspect-ratio: 1; object-fit: cover; }
.evidence-instant-prints .ev-instant figcaption {
  position: static; max-width: none; min-height: 34px; padding: 8px 2px 7px;
  background: transparent; color: var(--ink); font-family: var(--mono);
  font-size: .58rem; letter-spacing: .035em; line-height: 1.1; white-space: normal;
}
.evidence-instant-prints .ev-instant-1 { rotate: -1.4deg; }
.evidence-instant-prints .ev-instant-2 { rotate: .8deg; }
.evidence-instant-prints .ev-instant-3 { rotate: -1deg; }
.evidence-instant-prints .ev-instant-4 { rotate: 1.3deg; }

@media (max-width: 980px) {
  /* The DOM already follows the narrow-screen reading order: introduction,
     evidence, optional context, actions. No CSS reordering is needed. */
  .project-preview.is-snapshot {
    grid-template-columns: 1fr;
    grid-template-rows: auto;
    grid-template-areas: "head" "media" "body" "foot";
    row-gap: clamp(22px, 5.5vw, 34px);
    align-items: start;
  }
  .is-snapshot .preview-head { grid-area: head; }
  .is-snapshot .preview-media { grid-area: media; }
  .is-snapshot .preview-body { grid-area: body; }
  .is-snapshot .preview-foot { grid-area: foot; }
  .is-snapshot .ev-group { display: grid; gap: clamp(12px, 3.2vw, 18px); min-width: 0; }

  .evidence-desktop-pair { padding-bottom: 38px; }
  .evidence-desktop-pair .ev-group-lead {
    grid-template-columns: 1fr;
    gap: 34px;
  }
  .ev-desktop-monitor { width: min(100%, 620px); justify-self: center; }

  .evidence-desktop-phone { min-height: clamp(270px, 86vw, 340px); }
  .is-snapshot .evidence-desktop-phone .ev-group-lead,
  .is-snapshot .evidence-desktop-phone .ev-group-support {
    position: absolute; display: block;
  }
  .evidence-desktop-phone .ev-group-lead { top: 2%; width: 84%; }
  .evidence-desktop-phone .ev-group-support { width: 31%; }
  .evidence-desktop-phone .desktop-monitor-shell {
    padding: 5px 5px 16px;
    border-radius: 8px 8px 5px 5px;
    box-shadow: 0 10px 18px rgba(38, 51, 59, .16);
  }
  .evidence-desktop-phone .desktop-monitor-stand { height: 15px; }
  .evidence-desktop-phone .ev-product-phone {
    border-width: 4px; border-radius: 18px;
    box-shadow: 6px 8px 0 rgba(38,51,59,.2);
  }
  .evidence-desktop-phone .ev-product-phone img { border-radius: 13px; }

  .evidence-mobile-share { min-height: clamp(350px, 108vw, 430px); }
  .is-snapshot .evidence-mobile-share .ev-group-lead,
  .is-snapshot .evidence-mobile-share .ev-group-support {
    position: absolute; display: block;
  }
  .evidence-mobile-share .ev-group-lead { left: 1%; bottom: 0; width: 42%; }
  .evidence-mobile-share .ev-group-support { right: 0; top: 4%; width: 62%; }
  .evidence-mobile-share .ev-golf-search-phone {
    border-width: 4px; border-radius: 18px;
    box-shadow: 6px 8px 0 rgba(38,51,59,.2);
  }
  .evidence-mobile-share .ev-golf-search-phone img { border-radius: 13px; }
  .evidence-mobile-share .ev-golf-share-card {
    filter: drop-shadow(7px 9px 0 rgba(38,51,59,.18));
  }

  .evidence-project-desktop { min-height: 0; }
  .project-desktop-files {
    min-height: 0;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 40px 18px;
    padding: 46px 18px 48px;
  }
  .project-desktop-file:nth-child(n) { margin: 0; }
  .project-desktop-file:nth-child(even) { margin-top: 22px; }
  .project-desktop-file:last-child:nth-child(odd) {
    grid-column: 1 / -1;
    width: 50%;
    justify-self: center;
  }
  .project-file-folder { width: clamp(84px, 28vw, 112px); }

  /* Overlapping evidence becomes an ordinary stack. Nothing is hidden. */
  /* relative, not static: the frame is still the containing block for its own
     caption and for the progression marker. Taking it out of the positioned
     flow entirely sent both to the folder's bottom-left corner. */
  .is-snapshot .evidence-progression .ev-frame,
  .is-snapshot .evidence-hero-inset .ev-frame {
    position: relative; inset: auto; width: 100%; rotate: none;
  }
  .is-snapshot .evidence-hero-inset .ev-inset { box-shadow: 10px 12px 0 rgba(38, 51, 59, .18); }
  .evidence-browser-sections {
    display: grid;
    gap: 18px;
    min-height: 0;
  }
  .evidence-browser-motion .ev-motion-sequence { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
  .ev-motion-step::after { display: none; }
  .evidence-browser-motion .ev-group-support { grid-template-columns: 1fr; }
  .ev-tool-strip { grid-template-columns: repeat(5, minmax(0, 1fr)); }
  .ev-tool-strip span { display: grid; place-items: center; min-height: 38px; padding: 5px; border-top: 0; border-left: var(--hairline); text-align: center; }
  .ev-tool-strip span:first-child { border-left: 0; }
  .is-snapshot .evidence-browser-sections .ev-group { display: block; }
  .ev-browser-hero,
  .ev-browser-motion {
    position: relative;
    inset: auto;
    width: 100%;
    rotate: none;
  }
  /* On the image, not the figure: the progression's caption is inside the
     figure at this width, so a shadow on the figure draws a grey band beside
     and under the label rather than behind the capture. */
  .is-snapshot .evidence-progression .ev-front { box-shadow: none; }
  .is-snapshot .evidence-progression .ev-front img { box-shadow: 10px 12px 0 rgba(38, 51, 59, .18); }
  /* The progression's labels come OUT of the frame on a phone. Overlaid, they
     land on the bottom-left of a 3:2 capture, which is where the tribute card's
     dates sit in step 1 and its new service block sits in step 2 — the two rows
     the composition exists to show changing. Desktop keeps them overlaid: there
     the frames overlap, and a label off the edge is what joins them. */
  .is-snapshot .evidence-progression .ev-frame figcaption {
    position: static; inset: auto; translate: 0 0;
    width: max-content; max-width: 100%; margin-top: 6px;
    font-size: .72rem; white-space: normal;
  }
  .is-snapshot .evidence-search-share .ev-frame figcaption {
    position: static; inset: auto;
    width: 100%; max-width: 100%; box-sizing: border-box;
    white-space: normal; overflow-wrap: anywhere;
  }
  .is-snapshot .evidence-search-share .ev-frame { min-width: 0; }
  .is-snapshot .evidence-hero-inset .ev-inset figcaption { font-size: .68rem; }
  /* The progression reads downwards, so it gets a real progression marker
     between the two states rather than relying on the reader inferring it. */
  .is-snapshot .evidence-progression .ev-group-lead { row-gap: clamp(20px, 5vw, 28px); }
  .is-snapshot .evidence-progression .ev-behind::after {
    content: ""; position: absolute; left: 50%; bottom: calc(-1 * clamp(20px, 5vw, 28px));
    translate: -50% 0; margin-bottom: 6px;
    border-left: 7px solid transparent; border-right: 7px solid transparent;
    border-top: 9px solid var(--ink);
  }

  .evidence-stack .ev-pair { grid-template-columns: 1fr; }
  .evidence-search-share .ev-search-share-pair { grid-template-columns: 1fr; }
  .evidence-comparison .ev-compare-pair { grid-template-columns: 1fr; }
  .evidence-phone-fan .phones { min-height: clamp(360px, 112vw, 500px); padding-inline: 0; }
  .evidence-phone-fan .phone { border-width: 4px; border-radius: 22px; box-shadow: 7px 9px 0 rgba(38,51,59,.2); }
  .evidence-phone-fan .phone img { border-radius: 16px; }
  .evidence-phone-fan .ev-group-support { grid-template-columns: 1fr; }
  .evidence-photo-story { padding-bottom: 0; gap: 14px; }
  .evidence-photo-story .ev-group-support {
    position: static; width: 92%; margin: -13% 0 0 auto;
    grid-template-columns: minmax(0, 1.2fr) minmax(90px, .8fr);
    box-shadow: 9px 11px 0 rgba(38,51,59,.18);
  }
  .evidence-photo-story .ev-group-support:has(> :only-child) {
    width: 66%; grid-template-columns: 1fr;
  }
  .evidence-instant-prints { min-height: 0; padding: 4px 2px 10px; }
  .evidence-instant-prints .ev-group-lead {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 13px 10px; width: 100%; min-height: 0;
  }
  .evidence-instant-prints .ev-instant { width: auto; padding: 6px 6px 0; box-shadow: 5px 6px 0 rgba(38,51,59,.15); }
  .evidence-instant-prints .ev-instant figcaption { min-height: 30px; padding: 7px 1px 6px; font-size: .53rem; }
  /* Three columns of component captures are unreadable on a phone; two keep
     each tile wide enough to still read as a set of controls. */
  .evidence-system .ev-mosaic { columns: 2; }

  /* A purpose-made narrow capture has its own shape; the desktop width and
     height attributes would otherwise reserve the wrong box and shift. */
  .ev-frame img,
  .ev-frame video { aspect-ratio: var(--m-ar, var(--ar, auto)); }

  /* The shared contribution grid is two max-content columns, which was decided
     when every label was one or two short words. These labels are longer, and
     two max-content columns of "Trade-show activation design" and "Brand
     positioning & messaging" set a min-content width of ~399px inside a 305px
     column, which blew the whole page out horizontally. Snapshots only: two
     equal columns that are allowed to shrink, so the 2 by 2 grid survives and
     the text wraps instead of the page. Every other project keeps the original
     rule at every width. */
  .is-snapshot .project-scope ul { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  .is-snapshot .project-scope li { align-items: flex-start; }

  .metric-group.is-inline { grid-template-columns: repeat(auto-fit, minmax(125px, 1fr)); }
  .metric-group.is-inline .metric + .metric { padding-left: 12px; border-left: 1px solid rgba(21,25,24,.28); border-top: 0; }
  .metric-group.is-hero .metric-value { font-size: clamp(2.8rem, 14vw, 4.6rem); }
}

.contact-body { max-width: 46ch; margin: 24px 0 0 !important; color: rgba(255,255,255,.78); font-size: clamp(1rem, 1.4vw, 1.25rem); }

@media (prefers-reduced-motion: reduce) {
  .project-file-folder { transition: none; }
}

/* Deathcare is a three-part research proof, not three dashboard cards. Keep
   each number and its short label together in one compact, aligned band. */
#preview-deathcaresoftware .metric-group.is-inline { grid-template-columns: repeat(3, minmax(0, 1fr)); }
#preview-deathcaresoftware .metric-group.is-inline .metric {
  min-width: 0; padding: 13px 8px 14px;
  display: flex; align-items: baseline; justify-content: flex-start; gap: 6px;
  white-space: nowrap;
}
#preview-deathcaresoftware .metric-group.is-inline .metric:first-child { padding-left: 0; }
#preview-deathcaresoftware .metric-group.is-inline .metric-value {
  flex: none; font-size: clamp(1.35rem, 5.8vw, 1.9rem); font-variant-numeric: tabular-nums;
}
#preview-deathcaresoftware .metric-group.is-inline .metric-label {
  min-width: 0; margin: 0; font-size: clamp(.7rem, 2.9vw, .88rem); line-height: 1;
}

/* ═══════════════════════════════════════════════════════════════════════
   EXPANDED OPEN DRAWER PROTOTYPE — 2026-09-26

   One generous desktop scene, not a complete case study squeezed into a
   small card. The filing system stays intact; the browser width now belongs
   to the work. Snapshot height remains content-led: one viewport is the
   editorial preference, never a clipping or fixed-height rule.
   ═══════════════════════════════════════════════════════════════════════ */
@media (min-width: 981px) {
  .experience {
    padding: clamp(28px, 4vh, 52px) clamp(16px, 1.6vw, 32px)
      clamp(72px, 8vw, 128px);
  }

  .drawer {
    width: min(100%, 1840px);
    max-width: none;
  }

  .capability-tabs {
    padding-inline: clamp(16px, 2.2vw, 40px);
  }

  .capability-tab {
    min-height: 72px;
    padding: 13px 18px 24px;
  }

  .capability-tab[aria-selected="true"] {
    min-height: 84px;
    padding-bottom: 14px;
  }

  .folder {
    min-height: clamp(620px, calc(100svh - 170px), 760px);
    padding: clamp(24px, 2.35vw, 44px);
  }

  .folder-body {
    padding-top: clamp(22px, 2vw, 36px);
  }

  .project-preview.is-snapshot {
    grid-template-columns: minmax(300px, .62fr) minmax(0, 1.38fr);
    column-gap: clamp(32px, 3.6vw, 68px);
  }

  .is-snapshot.layout-image,
  .is-snapshot.layout-photo,
  .is-snapshot.layout-moment {
    grid-template-columns: minmax(0, 1.32fr) minmax(300px, .68fr);
  }

  .is-snapshot.layout-copy {
    grid-template-columns: minmax(320px, 1fr) minmax(0, 1fr);
  }

  .is-snapshot .preview-head h4 {
    font-size: clamp(2rem, 2.45vw, 3.2rem);
  }

  .layout-comparison .preview-head h4,
  .layout-motion .preview-head h4,
  .layout-copy .preview-head h4 {
    max-width: 20ch;
    font-size: clamp(2.25rem, 3.2vw, 4.1rem);
  }

  .is-snapshot .preview-short {
    margin-top: clamp(18px, 1.5vw, 24px);
    font-size: clamp(1.04rem, 1.15vw, 1.25rem);
  }

  .evidence-desktop-phone {
    height: clamp(480px, 29vw, 570px);
    min-height: 0;
  }

  /* These compositions were originally percentage-sized inside a 1400px
     drawer. Once the drawer can use a wide monitor, their portrait artefacts
     become taller than the folder. Cap the physical artefacts, not the new
     evidence column, so the scene keeps its breathing room and hierarchy. */
  .evidence-desktop-phone .ev-group-lead {
    top: 2%;
    width: min(76%, 780px);
  }

  .evidence-desktop-phone .ev-group-support {
    width: min(27%, 250px);
  }

  .evidence-mobile-share {
    height: clamp(470px, 27vw, 540px);
    min-height: 0;
  }

  .evidence-mobile-share .ev-group-lead {
    left: 4%;
    width: clamp(210px, 20vw, 260px);
  }

  .evidence-mobile-share .ev-group-support {
    top: 12px;
    right: 4%;
    width: min(64%, 660px);
    height: calc(100% - 24px);
  }

  .evidence-mobile-share .ev-golf-share-card {
    height: 100%;
    overflow: hidden;
  }

  .evidence-mobile-share .ev-golf-share-card img {
    height: 100%;
    object-fit: cover;
    object-position: center top;
  }

  /* The live before/after wipe keeps its native 3:2 screen, so cap that
     screen rather than flattening or cropping it on an ultra-wide canvas. */
  .evidence-live-only:has(.ev-live-wipe) {
    width: min(100%, 940px);
    margin-inline: auto 0;
  }

  /* The two onboarding states should read as a transition, not turn into an
     extra-tall poster as the media column widens. Both source frames remain
     visible and the full images are still available through the loupe. */
  .evidence-progression {
    height: clamp(480px, 32vw, 680px);
    aspect-ratio: auto;
  }
}
