@font-face { font-family: 'Hanken Grotesk'; src: url('/assets/hanken-grotesk-latin.woff2') format('woff2'); font-weight: 400 700; font-style: normal; font-display: swap; }
@font-face { font-family: 'Caveat'; src: url('/assets/caveat-latin.woff2') format('woff2'); font-weight: 400 700; font-style: normal; font-display: swap; }
:root {
  color-scheme: light;
  --paper: #F0FAFB;
  --ink: #625953;
  --muted: #756b64;
  --accent: #C92C70;
  --forest: #28513c;
  --line: #52776c55;
  --ink-strong: color-mix(in oklch, #625953 35%, black);
  --chip: rgba(252, 254, 254, .92);
  --highlight: color-mix(in oklch, #C92C70 20%, #ffffff);
  /* Keyboard-only focus ring (Tab), raspberry; mouse clicks don't show it */
  --focus-ring: var(--accent);
  --chip-shadow: 0 1px 2px rgba(0,0,0,.06), 0 10px 22px -12px rgba(40,50,60,.45);
  font-family: 'Hanken Grotesk', Arial, sans-serif;
  font-synthesis: none;
  -webkit-font-smoothing: antialiased;
  color: var(--ink);
  background: var(--paper);
}
/* Night mode: toggled by the corner button, saved in localStorage */
:root.night {
  color-scheme: dark;
  --paper: #121a1d;
  --ink: #cfc7c1;
  --muted: #9d948d;
  --ink-strong: #f2ede8;
  --accent: #e2558f;
  --forest: #9cc4ae;
  --line: #9cc4ae33;
  --chip: rgba(30, 40, 44, .92);
  --highlight: color-mix(in oklch, #e2558f 38%, #121a1d);
  --chip-shadow: 0 1px 2px rgba(0,0,0,.2), 0 10px 22px -12px rgba(0,0,0,.7);
}
:root.night .landscape { opacity: .4; filter: brightness(.75); }
:root.night body::after { opacity: .22; } /* grain reads as grey static on a dark ground */
/* Switch themes in one frame instead of a ragged cascade of per-element transitions */
:root.theme-switching * { transition: none !important; }
/* Light/dark cross-fade (View Transitions, started by the mode button). Dial: 1500ms */
::view-transition-old(root), ::view-transition-new(root) { animation-duration: 1000ms; animation-timing-function: cubic-bezier(.4, 0, .2, 1); }
/* Cursors: glyphs from Smileyface Font by Jonathan Macagba (shareware, $5; see Downloads/smileyface/readme.txt).
   Default "a" = smile; clickable "t" = wink. 20px, about the size of the system arrow; hotspot in the middle.
   Day versions have a white halo, night versions a dark one, so they show on either background. */
html { cursor: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20width='20'%20height='20'%20viewBox='0%200%20578%20578'%3E%3Cg%20transform='translate%28-88.9%20647.0%29%20scale%281%20-1%29'%3E%3Cpath%20d='M527%20517Q527%20505%20517.5%20495.5Q508%20486%20495%20486Q482%20486%20472.5%20495.5Q463%20505%20463%20517Q463%20530%20472.5%20539.5Q482%20549%20495%20549Q508%20549%20517.5%20539.5Q527%20530%20527%20517ZM276%20517Q276%20505%20266.5%20495.5Q257%20486%20245%20486Q232%20486%20222.0%20495.0Q212%20504%20212%20517Q212%20530%20221.5%20539.5Q231%20549%20245%20549Q257%20549%20266.5%20539.5Q276%20530%20276%20517ZM627%20385Q627%20290%20550%20227Q478%20167%20377%20167Q278%20167%20208%20227Q135%20289%20129%20385Q128%20403%20146%20403Q162%20403%20163%20386Q168%20306%20230.5%20253.5Q293%20201%20378%20201Q463%20201%20525.0%20253.5Q587%20306%20592%20386Q593%20403%20609%20403Q627%20403%20627%20385Z'%20fill='%232b2522'%20stroke='%23ffffff'%20stroke-width='74'%20stroke-linejoin='round'%20paint-order='stroke'/%3E%3C/g%3E%3C/svg%3E") 10 10, auto; }
a, button, summary, [role='button'], .note { cursor: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20width='20'%20height='20'%20viewBox='0%200%20578%20578'%3E%3Cg%20transform='translate%28-88.9%20649.0%29%20scale%281%20-1%29'%3E%3Cpath%20d='M566%20518%20457%20479Q454%20478%20451%20478Q434%20478%20434%20497Q434%20509%20445%20513L553%20552Q556%20553%20559%20553Q577%20553%20577%20533Q577%20522%20566%20518ZM280%20517Q280%20504%20270.0%20495.0Q260%20486%20247%20486Q235%20486%20225.5%20495.5Q216%20505%20216%20517Q216%20530%20225.5%20539.5Q235%20549%20247%20549Q261%20549%20270.5%20539.5Q280%20530%20280%20517ZM627%20385Q627%20290%20550%20227Q478%20167%20377%20167Q278%20167%20208%20227Q135%20289%20129%20385Q128%20403%20146%20403Q162%20403%20163%20386Q168%20306%20230.5%20253.5Q293%20201%20378%20201Q463%20201%20525.0%20253.5Q587%20306%20592%20386Q593%20403%20609%20403Q627%20403%20627%20385Z'%20fill='%232b2522'%20stroke='%23ffffff'%20stroke-width='74'%20stroke-linejoin='round'%20paint-order='stroke'/%3E%3C/g%3E%3C/svg%3E") 10 10, pointer; }
:root.night { cursor: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20width='20'%20height='20'%20viewBox='0%200%20578%20578'%3E%3Cg%20transform='translate%28-88.9%20647.0%29%20scale%281%20-1%29'%3E%3Cpath%20d='M527%20517Q527%20505%20517.5%20495.5Q508%20486%20495%20486Q482%20486%20472.5%20495.5Q463%20505%20463%20517Q463%20530%20472.5%20539.5Q482%20549%20495%20549Q508%20549%20517.5%20539.5Q527%20530%20527%20517ZM276%20517Q276%20505%20266.5%20495.5Q257%20486%20245%20486Q232%20486%20222.0%20495.0Q212%20504%20212%20517Q212%20530%20221.5%20539.5Q231%20549%20245%20549Q257%20549%20266.5%20539.5Q276%20530%20276%20517ZM627%20385Q627%20290%20550%20227Q478%20167%20377%20167Q278%20167%20208%20227Q135%20289%20129%20385Q128%20403%20146%20403Q162%20403%20163%20386Q168%20306%20230.5%20253.5Q293%20201%20378%20201Q463%20201%20525.0%20253.5Q587%20306%20592%20386Q593%20403%20609%20403Q627%20403%20627%20385Z'%20fill='%23f2ede8'%20stroke='%23121a1d'%20stroke-width='74'%20stroke-linejoin='round'%20paint-order='stroke'/%3E%3C/g%3E%3C/svg%3E") 10 10, auto; }
:root.night a, :root.night button, :root.night summary, :root.night [role='button'], :root.night .note { cursor: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20width='20'%20height='20'%20viewBox='0%200%20578%20578'%3E%3Cg%20transform='translate%28-88.9%20649.0%29%20scale%281%20-1%29'%3E%3Cpath%20d='M566%20518%20457%20479Q454%20478%20451%20478Q434%20478%20434%20497Q434%20509%20445%20513L553%20552Q556%20553%20559%20553Q577%20553%20577%20533Q577%20522%20566%20518ZM280%20517Q280%20504%20270.0%20495.0Q260%20486%20247%20486Q235%20486%20225.5%20495.5Q216%20505%20216%20517Q216%20530%20225.5%20539.5Q235%20549%20247%20549Q261%20549%20270.5%20539.5Q280%20530%20280%20517ZM627%20385Q627%20290%20550%20227Q478%20167%20377%20167Q278%20167%20208%20227Q135%20289%20129%20385Q128%20403%20146%20403Q162%20403%20163%20386Q168%20306%20230.5%20253.5Q293%20201%20378%20201Q463%20201%20525.0%20253.5Q587%20306%20592%20386Q593%20403%20609%20403Q627%20403%20627%20385Z'%20fill='%23f2ede8'%20stroke='%23121a1d'%20stroke-width='74'%20stroke-linejoin='round'%20paint-order='stroke'/%3E%3C/g%3E%3C/svg%3E") 10 10, pointer; }
* { box-sizing: border-box; }
body { position: relative; margin: 0; isolation: isolate; }
body::after { content: ''; position: fixed; inset: 0; z-index: 5; pointer-events: none; opacity: .65; mix-blend-mode: soft-light; background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 180 180' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.5' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Cpath fill='%23000' filter='url(%23n)' opacity='.7' d='M0 0h180v180H0z'/%3E%3C/svg%3E"); background-size: 180px 180px; }
a { color: inherit; text-decoration: none; }
a:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 6px; border-radius: 2px; }
.skip-link { position: fixed; top: -70px; left: 24px; padding: 12px; background: var(--paper); z-index: 10; }
.skip-link:focus { top: 12px; }
.site-header { position: absolute; top: 30px; left: 24px; }
.name { font-size: 14px; line-height: 24px; letter-spacing: -.2px; }
.name:hover { color: var(--accent); }
.navigation { position: fixed; top: 240px; left: 24px; display: flex; flex-direction: column; gap: 2px; }
.navigation a { position: relative; width: fit-content; color: var(--muted); font-size: 14px; line-height: 27px; transition: color 150ms ease; }
.navigation a:hover, .navigation a[aria-current] { color: var(--accent); }
.navigation a[aria-current]::before { content: ''; position: absolute; width: 2px; height: 20px; left: -12px; top: 3.5px; background: var(--accent); }
.navigation a[aria-current]::after { content: ''; position: absolute; width: 9px; height: 5px; left: -11px; top: 8px; background: var(--accent); border-radius: 9px 0 9px 0; transform: rotate(-30deg) scale(0); transform-origin: left bottom; transition: transform 240ms ease; }
.navigation a[aria-current]:is(:hover, :focus-visible)::after { transform: rotate(-30deg) scale(1); }
main { --center-gap: calc((100vw - 1120px) / 2); margin-left: max(188px, var(--center-gap)); margin-right: max(clamp(24px, 6vw, 104px), var(--center-gap)); width: auto; max-width: 1120px; padding-top: 231px; padding-bottom: 100px; min-height: 75svh; display: flex; flex-direction: column; }
main:focus { outline: none; }
h1 { font-family: inherit; font-weight: 600; font-size: clamp(60px, 6vw, 84px); letter-spacing: -3px; line-height: 1.1; margin: 0 0 25px; }
.heading-dot { color: var(--accent); }
.about-bio { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: clamp(32px, 5vw, 72px); font-size: 17px; line-height: 1.85; }
.about-bio p { margin: 0 0 24px; }
.about-bio a { color: var(--accent); text-decoration: underline; text-underline-offset: 4px; }
.about-bio a:hover { text-decoration-thickness: 2px; }
.visually-hidden { position: absolute; width: 1px; height: 1px; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
/* Travel map: fixed 340px, same as the previous portfolio */
.map-block iframe { display: block; width: 100%; height: 340px; border: 0; border-radius: 0; }
.page-gallery .map-block { margin-bottom: 56px; scroll-margin-top: 40px; }
.map-block > a { display: inline-block; margin-top: 14px; color: var(--accent); font-size: 14px; text-decoration: underline; text-underline-offset: 4px; }
.map-block .map-note { max-width: 62ch; margin: 28px 0 0; font-size: 15px; line-height: 1.6; color: var(--ink); text-wrap: pretty; }
.content-section { margin-top: 94px; }
h2 { font-size: 13px; font-weight: 400; color: var(--muted); margin: 0 0 18px; }
@media (max-width: 640px) {
  .site-header { top: 24px; }
  .navigation { top: 0; left: 0; right: 0; z-index: 2; flex-direction: row; gap: 20px; padding: 24px 24px 14px; background: var(--paper); overflow-x: auto; scrollbar-width: none; }
  .site-header { position: fixed; z-index: 3; }
  .navigation a[aria-current]::before { width: 100%; height: 2px; top: auto; bottom: -3px; left: 0; }
  .navigation a[aria-current]::after { display: none; }
  main { width: auto; margin: 0 16px; padding-top: 110px; }
  h1 { font-size: 64px; }
  .content-section { margin-top: 70px; }
}
@media (prefers-reduced-motion: reduce) { * { transition: none !important; } }

.landscape { width: 100%; height: max(46vh, 360px); background: url('/assets/landscape-2400.jpg') center 64% / cover no-repeat; mask-image: linear-gradient(transparent, #000 65%); opacity: .75; }
@media (max-width: 640px) { main { padding-bottom: 72px; } .landscape { height: 380px; } }

/* ---- Prototype layout ---- */
.muted { color: var(--muted); }
.lede { font-size: 17px; line-height: 1.7; margin: 0 0 48px; max-width: 56ch; }
.about-bio { margin-bottom: 8px; }
@media (max-width: 800px) { .about-bio { grid-template-columns: 1fr; gap: 0; } }

/* Home: intro + history */
/* Name in Caveat to match Figma. Handwriting reads small, so size up and keep default tracking */
/* Home name size + gap below it. Gallery/Travel/Writing reserve the same space so their first block lines up with "I'm a recent UW…" */
:root { --name-size: clamp(44px, 4vw, 56px); --name-block: calc(var(--name-size) + 24px); }
:is(.page-gallery, .page-travel, .page-writing)::before { content: ''; display: block; height: var(--name-block); flex: none; }
.page-work h1 { font-family: 'Caveat', 'Bradley Hand', cursive; font-weight: 500; font-size: var(--name-size); letter-spacing: 0; line-height: 1; margin-bottom: 24px; color: var(--ink-strong); }
/* Intro column = its own text measure (58ch); the rest goes to Previously at so each line fits on one row */
.hero { display: grid; grid-template-columns: minmax(0, 58ch) minmax(0, 1fr); gap: clamp(32px, 4vw, 56px); align-items: start; }
.hero-intro p { font-size: 16px; line-height: 1.65; margin: 0 0 16px; max-width: 58ch; }
.contact { list-style: none; padding: 0; margin: 28px 0 0; display: flex; flex-wrap: wrap; gap: 8px 22px; font-size: 14px; }
.contact li { position: relative; }
.contact a, .copy-email { color: var(--accent); font: inherit; background: none; border: 0; padding: 0; text-decoration: underline; text-underline-offset: 4px; text-decoration-color: color-mix(in oklch, var(--accent) 40%, transparent); }
.contact a:hover, .copy-email:hover { text-decoration-color: var(--accent); }
.copy-email:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 6px; border-radius: 2px; }
.copied { position: absolute; left: 0; top: 100%; margin-top: 4px; font-size: 12px; color: var(--muted); white-space: nowrap; }
.hero-intro p a { text-decoration: underline; text-underline-offset: 3px; text-decoration-color: color-mix(in oklch, var(--ink) 40%, transparent); }
.hero-intro p a:hover { color: var(--accent); text-decoration-color: var(--accent); }
/* "Previously at:" disclosure, native <details> like jia.sc. Figma look: no rules, dark first line, grey notes */
.history-block summary { width: fit-content; color: var(--ink-strong); font-size: 14px; transition: opacity 150ms ease; }
.history-block summary::marker { color: var(--accent); }
.history-block + .history-block { margin-top: 22px; }
.history-block summary:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 6px; border-radius: 2px; }
@media (hover: hover) { .history-block summary:hover { opacity: .7; } }
.history-block h2 { display: inline; margin: 0; font-size: inherit; color: inherit; }
.history { list-style: none; padding: 0 0 0 20px; margin: 14px 0 0; font-size: 14px; line-height: 1.45; }
.history li { display: grid; grid-template-columns: minmax(0, 1fr) auto 40px; column-gap: 16px; margin-bottom: 18px; color: var(--ink-strong); }
.history .role, .history .year { text-align: right; font-variant-numeric: tabular-nums; }
.history .org { font-weight: 600; }
.history .history-note { grid-column: 1 / -1; font-size: 13px; color: var(--muted); }
.history .history-note strong { font-weight: 600; color: inherit; } /* bold, but same grey as the rest of the line */
/* Bullet's left edge sits on the same 20px line as the history text above; item text follows after it */
.fun-list { list-style: none; padding: 0 0 0 20px; margin: 14px 0 0; font-size: 14px; line-height: 1.45; color: var(--ink-strong); }
.fun-list li { position: relative; padding-left: 14px; margin-bottom: 8px; }
.fun-list li::before { content: ''; position: absolute; left: 0; top: calc(0.725em - 2.5px); width: 5px; height: 5px; border-radius: 50%; background: var(--muted); }

/* Cards */
.card-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 40px 28px; }
.card { display: block; min-width: 0; }
.card-visual { aspect-ratio: 4 / 3; border-radius: 10px; display: grid; place-items: center; background: color-mix(in oklch, var(--forest) 9%, var(--paper)); outline: 1px solid color-mix(in oklch, var(--forest) 12%, transparent); outline-offset: -1px; overflow: hidden; transition: transform 240ms cubic-bezier(.2, .8, .2, 1); }
.card-visual span { font-size: 24px; font-weight: 600; color: color-mix(in oklch, var(--forest) 70%, var(--paper)); letter-spacing: -1px; }
.card-visual img { width: 100%; height: 100%; object-fit: contain; padding: 18%; }
.card-visual img.cover { object-fit: cover; padding: 0; }
.card-body { padding-top: 14px; }

/* Home projects: two equal columns, square corners, one caption line */
.project-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 40px 24px; }
.project-grid .card-visual { aspect-ratio: 16 / 10; border-radius: 0; }
/* Alternative: add class "uneven" to .project-grid for wide + narrow rows that flip each row */
.project-grid.uneven { grid-template-columns: repeat(12, minmax(0, 1fr)); }
.project-grid.uneven > .card { grid-column: span 7; }
.project-grid.uneven > .card:nth-child(4n + 2), .project-grid.uneven > .card:nth-child(4n + 3) { grid-column: span 5; }
.project-grid.uneven .card-visual { aspect-ratio: auto; height: clamp(220px, 24vw, 324px); }
/* .card p (margin: 0; line-height: 1.6) was overriding this and gluing the caption to the image.
   10px + half-leading puts the glyphs ~13px under the image; 40px row gap keeps each caption clearly with its own card (~3:1). */
.project-card .project-caption { margin: 10px 0 0; font-size: 15px; line-height: 1.4; }
.project-name { color: var(--ink-strong); transition: color 150ms ease; }
.project-year { color: var(--muted); font-variant-numeric: tabular-nums; }
/* Card → case study: the name link stretches over the whole card; the ↗ sits above it and goes to the website */
.project-card { position: relative; }
.project-name.stretched::after { content: ''; position: absolute; inset: 0; }
.project-name.stretched:focus-visible { outline: none; }
.project-card:has(.stretched:focus-visible) .card-visual { outline: 2px solid var(--focus-ring); outline-offset: 4px; }
.project-sep { color: var(--muted); }
/* Year and slashes sit above the card-wide link, so they are plain text (not clickable) */
.project-year, .project-sep { position: relative; z-index: 1; cursor: auto; }
.project-external { position: relative; z-index: 1; color: var(--accent); text-decoration: underline; text-underline-offset: 3px; text-decoration-color: color-mix(in oklch, var(--accent) 35%, transparent); transition: text-decoration-color 150ms ease; }
.project-external::before { content: ''; position: absolute; inset: -10px -4px; } /* ~40px tall hit area */
@media (hover: hover) and (pointer: fine) {
  .has-case:hover:not(:has(.project-external:hover, .project-year:hover, .project-sep:hover)) .project-name { color: var(--accent); }
  .project-external:hover { text-decoration-color: var(--accent); }
}
.card-meta { display: flex; gap: 10px; align-items: center; font-size: 12px; color: var(--muted); font-variant-numeric: tabular-nums; }
.tag { padding: 2px 8px; border-radius: 99px; border: 1px solid var(--line); }
.card h3 { font-size: 17px; font-weight: 600; margin: 10px 0 4px; }
.card p { font-size: 15px; line-height: 1.6; margin: 0; }
.card .remark { margin-top: 8px; font-size: 13px; font-style: italic; color: var(--muted); }
.arrow { color: var(--accent); font-weight: 400; }

/* Writing */
@media (hover: hover) { .notes { list-style: none; padding: 0; margin: 0; font-size: 15px; line-height: 1.6; }
.notes li { display: grid; grid-template-columns: 110px 1fr; gap: 16px; padding: 14px 0; border-top: 1px solid var(--line); }
.notes li:last-child { border-bottom: 1px solid var(--line); }

/* Gallery */
/* Two staggered columns (packed at build time in site.mjs); one column on phones, in list order */
.gallery { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 24px; align-items: start; }
.gallery-column { display: flex; flex-direction: column; gap: 24px; }
@media (max-width: 640px) {
  .gallery { display: flex; flex-direction: column; gap: 20px; }
  .gallery-column { display: contents; }
}
.photo { margin: 0; }
.photo img { display: block; width: 100%; height: auto; border-radius: 0; background: color-mix(in oklch, var(--forest) 9%, var(--paper)); }
.photo-fill { border-radius: 6px; background: linear-gradient(calc(var(--i) * 37deg), color-mix(in oklch, var(--forest) 22%, var(--paper)), color-mix(in oklch, var(--accent) 10%, var(--paper))); }
.photo.tall .photo-fill { aspect-ratio: 3 / 4; }
.photo.wide .photo-fill { aspect-ratio: 3 / 2; }
.photo.square .photo-fill { aspect-ratio: 1; }
.photo figcaption { font-size: 12px; color: var(--muted); padding-top: 6px; }

/* About */
.jump { display: flex; gap: 8px; margin-top: 40px; }
.jump a { font-size: 14px; padding: 6px 14px; border-radius: 99px; border: 1px solid var(--line); color: var(--muted); transition: color 150ms ease, border-color 150ms ease; }
@media (hover: hover) { .jump a:hover { color: var(--accent); border-color: var(--accent); } }
.page-about .content-section { margin-top: 64px; scroll-margin-top: 40px; }

@media (max-width: 900px) {
  .hero { grid-template-columns: 1fr; }
}
@media (max-width: 640px) {
  .card-grid, .project-grid, .project-grid.uneven { grid-template-columns: 1fr; }
  .project-grid.uneven > .card:nth-child(n) { grid-column: auto; }
  .project-grid.uneven .card-visual { height: auto; aspect-ratio: 16 / 10; }
  .history { padding-left: 0; }
  .history li { grid-template-columns: minmax(0, 1fr) 40px; }
  .history .role { grid-column: 1; grid-row: 2; text-align: left; }
  .notes li { grid-template-columns: 1fr; gap: 2px; }
  .page-about .content-section { scroll-margin-top: 80px; }
}

/* ---- Polish ---- */
h1, h2, h3 { text-wrap: balance; }
.hero-intro p, .history .history-note, .card p { text-wrap: pretty; }
/* Long placeholder marks ("The AI Collective") stay centered and off the edges in narrow cards */
.card-visual span { padding: 0 20px; text-align: center; text-wrap: balance; user-select: none; }
/* Contact links: 44px-tall hit areas. Vertical extension (12px) = half the row gap; horizontal (11px) = half the column gap, so neighbors never overlap */
.contact { gap: 24px 22px; line-height: 20px; }
.contact a, .copy-email { position: relative; }
.contact a::before, .copy-email::before { content: ''; position: absolute; inset: -12px -11px; }
@media (max-width: 640px) {
  /* Horizontal mobile nav: room to grow vertically, 10px each side = half the 20px gap */
  .navigation a::before { content: ''; position: absolute; inset: -8px -10px; }
}
/* Room under the hero for the expanding dropdowns is reserved by the script in site.mjs (reserveHeroSide). */

/* ---- Corner: local clock + light/dark toggle (after cynthwang.com, as in Figma) ---- */
.corner { position: absolute; top: 22px; right: 24px; z-index: 4; display: flex; align-items: center; gap: 10px; }
.clock { height: 37px; min-width: 104px; /* fits '10:00:00 AM', so the boxes don't shift when the hour gains a digit */ display: grid; place-items: center; padding: 0 14px; background: var(--chip); color: var(--ink-strong); font: 500 13px/1 'Hanken Grotesk', Arial, sans-serif; font-variant-numeric: tabular-nums; letter-spacing: .02em; white-space: nowrap; box-shadow: var(--chip-shadow); }
.date { border: 0; transition: transform 300ms cubic-bezier(.2, .8, .2, 1); height: 37px; display: flex; align-items: center; gap: 7px; padding: 0 14px 0 11px; background: var(--chip); color: var(--ink-strong); font: 500 13px/1 'Hanken Grotesk', Arial, sans-serif; font-variant-numeric: tabular-nums; letter-spacing: .02em; white-space: nowrap; box-shadow: var(--chip-shadow); }
.date:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 4px; }
@media (hover: hover) { .date:hover { transform: translateY(-2px); } }
.date:active { transform: scale(.97); }
/* Season menu under the date box */
.season-picker { position: relative; }
.season-menu { position: absolute; top: calc(100% + 8px); left: 0; min-width: 100%; display: grid; padding: 5px; background: var(--chip); -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px); box-shadow: var(--chip-shadow); transform-origin: top left; animation: season-menu-in 160ms cubic-bezier(.2, .8, .2, 1); }
.season-menu[hidden] { display: none; }
@keyframes season-menu-in { from { opacity: 0; transform: translateY(-4px) scale(.97); } }
.season-opt { display: flex; align-items: center; gap: 9px; width: 100%; padding: 8px 10px; border: 0; background: none; color: var(--ink-strong); font: 500 13px/1 'Hanken Grotesk', Arial, sans-serif; text-align: left; white-space: nowrap; }
.season-opt svg { width: 16px; height: 16px; flex: none; }
@media (pointer: coarse) { .season-opt { min-height: 44px; } } /* finger-sized rows on touch screens (tablets) */
.season-opt small { font-size: 12px; color: var(--muted); font-weight: 400; }
.season-opt::after { content: ''; width: 14px; height: 14px; margin-left: auto; flex: none; }
.season-opt[aria-checked='true']::after { background: currentColor; -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12.5l4.5 4.5L19 7.5'/%3E%3C/svg%3E") center / contain no-repeat; mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12.5l4.5 4.5L19 7.5'/%3E%3C/svg%3E") center / contain no-repeat; } /* checkmark in the text color */
.season-opt span { margin-right: 14px; }
.season-opt:focus { outline: none; }
.season-opt:hover, .season-opt:focus-visible { background: color-mix(in oklch, var(--ink-strong) 8%, transparent); }
.season-opt:focus-visible { box-shadow: inset 0 0 0 2px var(--focus-ring); } /* keyboard: same ring color as the date box and mode button */
.ic-auto { fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
@media (prefers-reduced-motion: reduce) { .season-menu { animation: none; } }
/* Season icon in the date box: all four are in the HTML, <html data-season> (set in <head>) shows one */
.season-icon { display: grid; }
.season-icon svg { display: none; width: 16px; height: 16px; }
[data-season='winter'] .ic-winter, [data-season='spring'] .ic-spring, [data-season='summer'] .ic-summer, [data-season='fall'] .ic-fall { display: block; }
.ic-winter { fill: none; stroke: #5b8db8; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
.ic-spring { fill: #ef9fb6; } .ic-spring .ic-center { fill: #f2c94c; }
.ic-summer { fill: #f2b632; } .ic-summer .ic-line { fill: none; stroke: #f2b632; stroke-width: 1.6; stroke-linecap: round; }
.ic-fall { fill: #e8853a; }
.night .ic-winter { stroke: #9cc3e6; }
.mode { width: 37px; height: 37px; display: grid; place-items: center; padding: 0; border: 0; background: var(--chip); color: var(--ink-strong); box-shadow: var(--chip-shadow); transition: transform 300ms cubic-bezier(.2, .8, .2, 1); }
.mode:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 4px; }
@media (hover: hover) { .mode:hover { transform: translateY(-2px); } }
.mode:active { transform: scale(.96); }
.mode svg { width: 19px; height: 19px; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
.mode .moon, .night .mode .sun { display: none; }
.night .mode .moon { display: block; }

html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

@media (max-width: 640px) {
  /* Top of the screen belongs to the mobile nav: toggle goes bottom-right */
  .corner { position: fixed; top: auto; left: auto; right: 16px; bottom: calc(16px + env(safe-area-inset-bottom)); }
  .clock, .date { display: none; }
}

/* ---- Case studies (pop-up + fallback pages). Type: Hanken Grotesk only; sizes 24 / 16 / 13; weights 400 / 600 ---- */
.case-back { width: fit-content; font-size: 13px; color: var(--muted); transition: color 150ms ease; }
@media (hover: hover) { .case-back:hover { color: var(--accent); } }
.case-title, .case-modal .case-title { font-family: 'Hanken Grotesk', Arial, sans-serif; font-size: 24px; font-weight: 600; letter-spacing: -.2px; line-height: 1.25; color: var(--ink-strong); margin: 20px 0 24px; text-wrap: balance; }
.case-modal .case-title { margin-top: 0; padding-right: 48px; }
.case-hero img { display: block; width: 100%; height: auto; }
.case-body { max-width: 760px; font-size: 16px; line-height: 1.7; color: var(--ink); }
.case-body section { margin-top: 36px; scroll-margin-top: 40px; }
.case-body h2, .case-body h3, .case-body h4 { font-family: inherit; font-size: 16px; font-weight: 600; letter-spacing: 0; line-height: 1.5; color: var(--ink-strong); }
.case-body h2 { margin: 0 0 16px; }
.case-body h3 { margin: 36px 0 8px; }
.case-body h4 { margin: 24px 0 6px; }
.case-body p { margin: 0 0 16px; }
.case-body ul, .case-body ol { margin: 0 0 16px; padding-left: 22px; }
.case-body li { margin-bottom: 6px; }
.case-body strong { color: var(--ink-strong); font-weight: 600; }
.case-body a { color: var(--accent); text-decoration: underline; text-underline-offset: 3px; text-decoration-color: color-mix(in oklch, var(--accent) 40%, transparent); }
.case-body a:hover { text-decoration-color: var(--accent); }
.case-body blockquote { margin: 0 0 16px; padding-left: 16px; border-left: 2px solid var(--line); color: var(--muted); }
.case-body dl { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px 32px; margin: 24px 0; padding: 20px 0; border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }
.case-body dl div { min-width: 0; }
.case-body dt { font-size: 13px; color: var(--muted); margin-bottom: 2px; }
.case-body dd { margin: 0; font-size: 16px; line-height: 1.5; color: var(--ink-strong); }
.case-body .case-links { display: flex; flex-wrap: wrap; gap: 8px 24px; font-size: 13px; }
.case-body figure { margin: 28px 0; }
.case-body figure img, .case-body figure video { display: block; width: 100%; height: auto; }
.case-body figcaption { margin-top: 10px; font-size: 13px; line-height: 1.5; color: var(--muted); text-align: center; text-wrap: balance; }
.case-body table { width: 100%; border-collapse: collapse; margin: 0 0 16px; font-size: 13px; }
.case-body th, .case-body td { text-align: left; padding: 8px 12px 8px 0; border-bottom: 1px solid var(--line); vertical-align: top; }
.case-back-end { display: block; margin-top: 72px; }
/* Impact stats: number 24/600 + label 13 (same 3 sizes), hairline-separated cells */
.case-body .case-stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 1px; margin: 8px 0 16px; background: var(--line); border: 1px solid var(--line); }
.case-body .case-stats div { display: grid; align-content: start; gap: 4px; padding: 18px 16px; background: var(--paper); }
.case-body .case-stats strong { font-size: 24px; font-weight: 600; line-height: 1.2; letter-spacing: -.2px; color: var(--ink-strong); font-variant-numeric: tabular-nums; }
.case-body .case-stats span { font-size: 13px; line-height: 1.4; color: var(--muted); }
.case-body .case-meta { margin: -6px 0 8px; font-size: 13px; color: var(--muted); }
.case-body .case-remark { margin-top: 40px; color: var(--muted); font-style: italic; font-synthesis: style; } /* no italic font file: let the browser slant it */
.case-body .case-accent { color: var(--accent); } /* raspberry: key numbers and outcomes only */
.case-body em, .case-body i { font-synthesis: style; } /* no italic font file, so let the browser slant it */
.case-body .case-note { font-size: 13px; line-height: 1.5; color: var(--muted); }
.case-body .case-partner { margin-top: 36px; }
.case-body .case-logo { display: block; width: auto; max-width: 100%; height: 32px; margin-bottom: 12px; }
.case-body .case-logos { display: flex; flex-wrap: wrap; align-items: center; gap: 20px 36px; margin: 20px 0 28px; }
.case-body .case-logos img { display: block; width: auto; height: 28px; }
/* Clickable screenshots: a slow, small zoom inside the frame on hover (plus the cursor label from data-note) */
.case-body .case-img-link { display: block; overflow: hidden; text-decoration: none; }
.case-body .case-img-link img { transition: transform 350ms cubic-bezier(0.2, 0.7, 0.2, 1); }
@media (hover: hover) { .case-body .case-img-link:hover img { transform: scale(1.03); } }
.case-body .case-img-link:active img { transform: scale(1.01); transition-duration: 120ms; }
.case-body .case-img-link:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 3px; }
@media (prefers-reduced-motion: reduce) { .case-body .case-img-link img { transition: none; transform: none !important; } }
.case-body .case-photos.two { grid-template-columns: repeat(2, minmax(0, 1fr)); }
/* Inline diagram (AI Copilot architecture): site font and colours, so it follows light/dark mode */
.case-body .case-diagram { display: block; width: 100%; height: auto; color: var(--muted); font-family: inherit; }
.case-diagram .dg-step { fill: var(--paper); stroke: var(--ink-strong); stroke-width: 1; }
/* colour roles: blue = data and tools, blue tint = privacy step, green = the model step */
.case-diagram { --dg-blue: #2f5f8f; }
:root.night .case-diagram { --dg-blue: #9dbbdc; }
.case-diagram .dg-tool { fill: color-mix(in oklch, var(--dg-blue) 9%, var(--paper)); stroke: var(--dg-blue); stroke-width: 1; stroke-dasharray: 3 3; }
.case-diagram .dg-privacy { fill: color-mix(in oklch, var(--dg-blue) 9%, var(--paper)); stroke: var(--dg-blue); }
.case-diagram .dg-model { fill: color-mix(in oklch, var(--forest) 16%, var(--paper)); stroke: var(--forest); stroke-width: 1.5; }
.case-diagram .dg-name { fill: var(--ink-strong); font-size: 13.5px; font-weight: 600; text-anchor: middle; }
.case-diagram .dg-sub { fill: var(--muted); font-size: 12px; text-anchor: middle; }
.case-diagram .dg-title { fill: var(--muted); font-size: 12px; letter-spacing: .02em; }
.case-diagram .dg-arrow { stroke: currentColor; stroke-width: 1; }
/* Tabs (pill style): <div class="case-tabs"> with a role="tablist" row and role="tabpanel" panels */
.case-body .case-tabs { margin-top: 48px; padding-top: 28px; border-top: 1px solid var(--line); }
.case-body .case-tablist { display: flex; flex-wrap: wrap; gap: 6px 8px; margin-bottom: 28px; }
.case-body .case-tablist [role="tab"] { font: inherit; font-size: 15px; line-height: 1; padding: 7px 9px; border: 0; border-radius: 0; background: transparent; color: var(--muted); transition: color 150ms ease, background-color 150ms ease; }
@media (hover: hover) { .case-body .case-tablist [role="tab"][aria-selected="false"]:hover { color: var(--accent); } }
.case-body .case-tablist [role="tab"][aria-selected="true"] { background: var(--accent); color: var(--paper); }
.case-body .case-tablist [role="tab"]:focus-visible, .case-body .case-tabpanel:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
.case-body .case-tabpanel > :first-child { margin-top: 0; }
.case-body .case-tabpanel:focus { outline: none; }
/* Two-column row: <div class="case-split"><div>text</div><figure>media</figure></div>.
   Add "flip" to put the media on the left. Stacks to one column on phones (text first). */
.case-body .case-split { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.25fr); gap: 32px; align-items: center; margin: 36px 0; }
.case-body .case-split > * { min-width: 0; margin: 0; }
.case-body .case-split > * > :first-child { margin-top: 0; }
.case-body .case-split > * > :last-child { margin-bottom: 0; }
.case-body .case-split.flip { grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr); }
.case-body .case-split.flip > :first-child { order: 2; }
/* Three photos in a row: <figure class="case-photos"><img/><img/><img/><figcaption/></figure> */
.case-body .case-photos { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; }
.case-body .case-photos img { aspect-ratio: 3 / 2; object-fit: cover; }
.case-body .case-photos figcaption { grid-column: 1 / -1; margin-top: -2px; }
@media (max-width: 640px) {
  .case-body dl { grid-template-columns: 1fr; }
  .case-body .case-photos { grid-template-columns: 1fr; }
  .case-body .case-split, .case-body .case-split.flip { grid-template-columns: 1fr; gap: 16px; }
  .case-body .case-split.flip > :first-child { order: 0; }
}

/* ---- Writing (Figma 'writing' frame: plain list) ---- */
.writing-title { font-family: 'Hanken Grotesk', Arial, sans-serif; font-size: 20px; font-weight: 700; letter-spacing: 0; line-height: 1.3; color: var(--ink-strong); margin: 0 0 16px; }
.writing-intro { margin: 0 0 40px; font-size: 16px; line-height: 1.65; max-width: 58ch; color: var(--muted); text-wrap: pretty; } /* same size as the homepage intro */
.writing-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 22px; font-size: 14px; line-height: 1.6; }
.writing-list li { display: grid; }
.writing-list a, .writing-list strong { width: fit-content; font-weight: 700; color: var(--ink-strong); transition: color 150ms ease; }
.writing-list span { color: var(--muted); font-variant-numeric: tabular-nums; }
@media (hover: hover) { .writing-list a:hover { color: var(--accent); } }

/* Gallery reveal: only when JS is running (.js-reveal). Opacity + transform only, soft ease-out. */
/* Slow, visible rise: 40px over ~1.1s, fade slightly faster than the move so it never looks transparent at rest */
.gallery.js-reveal .photo { opacity: 0; transform: translateY(40px); transition: opacity 900ms cubic-bezier(0.25, 0.6, 0.3, 1), transform 1100ms cubic-bezier(0.25, 0.6, 0.3, 1); transition-delay: var(--reveal-delay, 0ms); }
.gallery.js-reveal .photo.is-in { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) { .gallery.js-reveal .photo { opacity: 1; transform: none; transition: none; } }

/* ---- Gallery collage prototype: photos only, uneven placement, hover tag ---- */
.gallery-collage { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: 24px; row-gap: 56px; align-items: start; }
.collage-item { position: relative; grid-column: var(--start) / span var(--span); margin-top: var(--top); }
.collage-item img { display: block; width: 100%; height: auto; }
/* "place / year" as a small handwritten sticker tag, tilted, tucked over the bottom-left corner */
.photo-tag { position: absolute; left: 12px; bottom: 12px; padding: 2px 6px; background: var(--highlight); color: var(--ink-strong); font: 500 13px/1.35 'Hanken Grotesk', Arial, sans-serif; white-space: nowrap; pointer-events: none; opacity: 0; }
/* Mouse users: in-photo tags stay hidden (text kept for screen readers); a label follows the cursor instead */
.cursor-tag { position: fixed; left: 0; top: 0; z-index: 6; padding: 2px 6px; background: var(--highlight); color: var(--ink-strong); font: 500 13px/1.35 'Hanken Grotesk', Arial, sans-serif; white-space: nowrap; pointer-events: none; opacity: 0; transition: opacity 150ms ease-out; will-change: transform; }
.cursor-tag.is-visible { opacity: 1; }
/* Hover note in running text: dotted underline (not a link); label follows the mouse via .cursor-tag,
   and shows under the words for keyboard focus and on touch (tap) */
.note { position: relative; text-decoration: underline dotted; text-decoration-thickness: 1.5px; text-underline-offset: 3px; text-decoration-color: color-mix(in oklch, var(--ink) 55%, transparent); }
.note:focus { outline: none; }
.note:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
.note-tag { position: absolute; left: 0; top: calc(100% + 6px); z-index: 6; padding: 2px 6px; background: var(--highlight); color: var(--ink-strong); font: 500 13px/1.35 'Hanken Grotesk', Arial, sans-serif; white-space: nowrap; pointer-events: none; opacity: 0; transition: opacity 150ms ease-out; }
.note:focus-visible .note-tag { opacity: 1; }
@media (hover: none) { .note:focus .note-tag { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .note-tag { transition: none; } }
@media (prefers-reduced-motion: reduce) { .cursor-tag { transition: none; } }
/* No hover on touch: show the tags all the time */
@media (hover: none) { .photo-tag { opacity: 1; } }
@media (max-width: 640px) {
  /* Phones: one column, but alternate widths/sides so it still feels uneven */
  .gallery-collage { grid-template-columns: 1fr; row-gap: 36px; }
  .collage-item { grid-column: 1; margin-top: 0; width: 88%; }
  .collage-item:nth-child(even) { justify-self: end; width: 76%; }
}

/* ---- Gallery grid: two columns, same tile size, same gap across and down ---- */
.gallery-grid { --gap: 22px; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--gap); }
.grid-item { position: relative; margin: 0; }
/* Uniform 3:2 tiles; a future portrait/square file gets center-cropped to keep rows aligned */
.grid-item img { display: block; width: 100%; height: auto; aspect-ratio: 3 / 2; object-fit: cover; }
/* Tag sits inside the tile so it never spills into the gap */
.gallery-grid .photo-tag { left: 12px; bottom: 12px; }
@media (max-width: 640px) { .gallery-grid { grid-template-columns: 1fr; --gap: 16px; } }

/* ---- Gallery photo viewer (<dialog>) ---- */
.gallery .photo[role='button']:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 4px; }
html:has(.lightbox[open]) { overflow: hidden; } /* no page scroll behind the viewer */
.lightbox { width: 100vw; height: 100dvh; max-width: none; max-height: none; margin: 0; padding: 0; border: 0; background: transparent; color: var(--ink-strong); overflow: hidden; }
.lightbox::backdrop { background: color-mix(in oklch, var(--paper) 94%, transparent); }
.lightbox-figure { height: 100%; margin: 0; padding: 72px 96px 48px; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 14px; }
.lightbox-img { display: block; max-width: min(1200px, 100%); max-height: calc(100dvh - 180px); width: auto; height: auto; object-fit: contain; box-shadow: 0 1px 2px rgba(0,0,0,.08), 0 24px 48px -24px rgba(40,50,60,.45); }
.lightbox-caption { padding: 2px 6px; background: var(--highlight); font: 500 13px/1.35 'Hanken Grotesk', Arial, sans-serif; }
.lightbox-btn { position: absolute; width: 37px; height: 37px; display: grid; place-items: center; padding: 0; border: 0; background: var(--chip); color: var(--ink-strong); box-shadow: var(--chip-shadow); font: 400 17px/1 'Hanken Grotesk', Arial, sans-serif; transition: transform 150ms ease-out; }
.lightbox-btn:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 4px; }
.lightbox-btn:active { transform: scale(.96); }
.lightbox-close { top: 22px; right: 24px; }
.lightbox-prev, .lightbox-next { top: 50%; margin-top: -18px; }
.lightbox-prev { left: 28px; }
.lightbox-next { right: 28px; }
/* Enter: soft fade + slight scale up; exit is quicker and quieter */
.lightbox[open] .lightbox-figure, .lightbox[open]::backdrop { animation: lightbox-in 220ms cubic-bezier(0.32, 0.72, 0, 1); }
.lightbox.is-closing .lightbox-figure, .lightbox.is-closing::backdrop { animation: lightbox-out 150ms ease-in forwards; }
@keyframes lightbox-in { from { opacity: 0; transform: scale(.97); } }
@keyframes lightbox-out { to { opacity: 0; transform: scale(.98); } }
.lightbox[open]::backdrop { animation-name: lightbox-fade-in; }
.lightbox.is-closing::backdrop { animation-name: lightbox-fade-out; }
@keyframes lightbox-fade-in { from { opacity: 0; } }
@keyframes lightbox-fade-out { to { opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .lightbox-figure, .lightbox::backdrop { animation: none !important; } }
@media (max-width: 640px) {
  .lightbox-figure { padding: 64px 12px 96px; }
  .lightbox-img { max-height: calc(100dvh - 200px); }
  .lightbox-prev, .lightbox-next { top: auto; bottom: calc(24px + env(safe-area-inset-bottom)); margin-top: 0; }
  .lightbox-prev { left: calc(50% - 47px); }
  .lightbox-next { right: calc(50% - 47px); }
}

/* Work: cards follow right under the intro and slide down when a dropdown opens */
@media (min-width: 901px) { .page-work .hero + .content-section { margin-top: 72px; } }

/* ---- Case study pop-up on the homepage (<dialog>) ---- */
html:has(.case-modal[open]) { overflow: hidden; }
.case-modal { width: min(1080px, calc(100vw - 48px)); height: calc(100dvh - 64px); max-width: none; max-height: none; margin: auto; padding: 0; border: 0; overflow: hidden; background: var(--paper); color: var(--ink); box-shadow: 0 1px 2px rgba(0,0,0,.08), 0 30px 60px -20px rgba(30,40,50,.45); }
.case-modal::backdrop { background: color-mix(in oklch, #1d2a2e 38%, transparent); }
.case-modal-scroll { height: 100%; overflow-y: auto; overscroll-behavior: contain; padding: 56px clamp(24px, 6vw, 72px) 72px; }
.case-modal-close { top: 16px; right: 16px; z-index: 1; }
.case-modal .case-body { max-width: none; } /* full width of the pop-up, lined up with the hero image */
/* Enter: fade + small rise; exit quicker */
.case-modal[open] { animation: case-in 240ms cubic-bezier(0.32, 0.72, 0, 1); }
.case-modal[open]::backdrop { animation: lightbox-fade-in 240ms cubic-bezier(0.32, 0.72, 0, 1); }
.case-modal.is-closing { animation: case-out 160ms ease-in forwards; }
.case-modal.is-closing::backdrop { animation: lightbox-fade-out 160ms ease-in forwards; }
@keyframes case-in { from { opacity: 0; transform: translateY(14px) scale(.985); } }
@keyframes case-out { to { opacity: 0; transform: translateY(8px) scale(.99); } }
@media (prefers-reduced-motion: reduce) { .case-modal, .case-modal::backdrop { animation: none !important; } }
@media (max-width: 640px) {
  .case-modal { width: 100vw; height: 100dvh; }
  .case-modal-scroll { padding: 60px 16px calc(48px + env(safe-area-inset-bottom)); }
}

/* Pop-ups take initial focus on their content (not the ✕), so no ring appears when opened with the mouse */
.case-modal-scroll:focus, .lightbox-figure:focus { outline: none; }

/* Card hover: frame stays put, the cover slowly zooms inside it; slight press on click.
   Pointing at the end link (or the plain year/slashes) leaves the card still — only that link reacts.
   Only cards that open a case study move. Mouse/trackpad only; off for reduced motion. */
.project-card .card-visual img.cover { transition: transform 450ms cubic-bezier(0.32, 0.72, 0, 1); }
.project-card.has-case .card-visual { transition: transform 150ms ease-out; }
@media (hover: hover) and (pointer: fine) {
  .has-case:hover:not(:has(.project-external:hover, .project-year:hover, .project-sep:hover)) .card-visual img.cover { transform: scale(1.035); }
}
.has-case:active:not(:has(.project-external:active, .project-year:active, .project-sep:active)) .card-visual { transform: scale(.985); }
@media (prefers-reduced-motion: reduce) {
  .project-card .card-visual img.cover, .project-card.has-case .card-visual { transition: none; }
  .has-case:hover .card-visual img.cover, .has-case:active .card-visual { transform: none; }
}

/* ---- Mountain photo at the top: same photo as the bottom, cropped to the peak + lake, fading down into the page ---- */
/* Height adapts to the window so the contact links + the top of the first project cards stay in the first view */
:root { --top-band: clamp(140px, calc(100vh - 535px), 380px); }
.landscape-top { position: absolute; top: 0; left: 0; right: 0; height: var(--top-band); background: url('/assets/landscape-2400.jpg') center 42% / cover no-repeat; mask-image: linear-gradient(#000 55%, transparent); opacity: .75; pointer-events: none; } /* crop: cloud-capped peak + ridge, a wide panoramic strip */
/* Name straddles the photo edge: its vertical center sits on the bottom of the band (end of the fade),
   so the top half is over the (fading) photo and the bottom half is on the background. 28px = half the name's height.
   Dial: the 1 multiplier — lower it to move the name up into the photo. */
main { padding-top: calc(var(--top-band) * 1 - 28px); }
.navigation { top: calc(var(--top-band) * 1 - 19px); }
:root.night .landscape-top { opacity: .4; filter: brightness(.75); }
/* Seasonal particles (snow / petals / fireflies / leaves) drawn on a canvas over the band (script in site.mjs); same fade so they disappear where the photo ends */
.season-fx { position: absolute; top: 0; left: 0; width: 100%; height: var(--top-band); mask-image: linear-gradient(#000 50%, transparent); pointer-events: none; }
.night .season-fx { opacity: .8; }
@media (max-width: 640px) {
  :root { --top-band: 230px; }
  .landscape-top, .season-fx { top: 62px; } /* start below the fixed mobile nav so the peak isn't hidden */
  .navigation { top: 0; }
  main { padding-top: calc(62px + var(--top-band) + 12px); }
}
.map-block .map-accent { font-weight: 600; color: var(--accent); }
