/* ===== Work page (from Figma "Web-portfolio-2026", frame 4:39518, 1730px design) ===== */
:root { --ui-font: "SF Pro Display", -apple-system, BlinkMacSystemFont, "Helvetica Neue", Ppneuemontreal, sans-serif; --ink: #000; --pill: #ececec; --hero: #919191; --accent: #161616; --sub: #989898; --card: #ececec; --gutter: 30px;
  /* The page scales with the window up to --max-w and holds there: --vw is one hundredth of the window width or of the cap, whichever is
     smaller, and every window-based measure uses it. The cap is a 27" screen (2560 wide), so a MacBook (1512 or 1728) and a 27" are filled edge to
     edge, and an ultrawide gets the 27" layout centred: the hero sits in a centred --max-w column and the card canvas (tools/canvas/
     index.template.html) reads the same cap for its scale, 1.48x the Figma frame at most. Spacing and the canvas use --vw; the type does not. */
  --max-w: 2560px; --vw: min(1vw, calc(var(--max-w) / 100));
  /* The card canvas stops earlier, at the Figma frame's own width: the script reads --canvas-max-w and wider windows get the design-size cards
     centred. (The footer drawing has the same cap, in css/site-foot.css.) */
  --canvas-max-w: 1730px;
  /* Type is set in steps, not fluidly: a size holds while the window is dragged and changes only at the widths where the heading would otherwise
     run to five lines (or, going up, fall to two). --step multiplies the design sizes, 46/26 for the heading and subtitle in the 1730 frame. */
  --step: 1;
  }
html, body { margin: 0; background: #fff; overflow-x: hidden; overflow-x: clip; }
body.work-page { color: var(--ink); font-family: Ppneuemontreal, "PP Neue Montreal", sans-serif; -webkit-font-smoothing: antialiased; }
a { color: inherit; text-decoration: none; }

/* ---- Header (Figma 169:18982: heading 44/60 #989898, italic accents #545454, subtitle 24/32 @80%, 20px gap) ---- */
/* Every value below is a variable with the design value as its fallback. The Work page's tuning panel (?tune, "Header type" group) sets the variables
   on .work-hero to try other sizes live; without it nothing is set and the fallbacks are the site. */
.work-hero { position: relative; z-index: 3; padding: var(--hero-top, 67px) var(--gutter) 0; max-width: var(--max-w); margin: 0 auto; box-sizing: border-box;
  /* a column of a set height: the heading at the top, the subtitle row at the foot, so the row (and the grid 24px under it) sits at the same place on
     the Work and Craft pages whatever the heading's length. The height is the Work heading's three lines plus the designed gap and the 46px row; a
     shorter heading leaves more air above the row, a longer one keeps the gap and pushes the row down. */
  display: flex; flex-direction: column; align-items: stretch; min-height: calc(var(--hero-top, 67px) + 3 * var(--h1-lh, 1.439) * var(--h1-base, 41px) * var(--step, 1) + var(--sub-gap, clamp(96px, 19.54 * var(--vw), 338px)) + 46px); }   /* nav bottom (13 + 44) + 10px gap; above the canvas so the fish tile is never clipped */
.work-hero h1 { margin: 0 0 var(--sub-gap, clamp(96px, 19.54 * var(--vw), 338px)); text-wrap: pretty; font-weight: var(--h1-weight, 400);   /* no lone word on the last line */   /* PP Neue Montreal Book */ color: var(--hero); letter-spacing: var(--h1-track, -0.0025em);
  /* 46/68 at -0.75% in the 1730px frame (Mandy's revision of Figma 169:18982's 44/60, from the tuner), stepped by --step below. One paragraph, no
     forced breaks: it wraps gutter to gutter, three or four lines at every width, the last one ending where the words end. */
  font-size: calc(var(--h1-base, 41px) * var(--step, 1)); line-height: var(--h1-lh, 1.439); text-wrap: pretty; }
.work-hero h1 .ac { font-family: Ppeditorialold, "PP Editorial Old", serif; font-style: italic; font-weight: var(--ac-weight, 400); color: var(--accent); font-size: var(--ac-size, .88em); }
/* accent runs use a different font/size: zero their inline line-height so only the 60px strut sets the line box. They never break across lines:
   "Google, Adobe, TikTok" and "UC Berkeley" move to the next line whole. */
.work-hero h1 .ac { line-height: 0; white-space: nowrap; }
/* the steps: 56/32 from a 27" up (three lines again on the 2560 column), 46/26 down to 1366, 40/23 down to 1152, 34/19 down to 1024, then a fixed 32/44 */
@media (min-width: 2240px) { :root { --step: 1.2174; } }
@media (max-width: 1365px) { :root { --step: .8696; } }
@media (max-width: 1151px) { :root { --step: .7391; } }
@media (max-width: 1023px) { .work-hero h1 { font-size: 32px; line-height: 44px; } }
@media (max-width: 767px) { :root { --step: .6957; } }
.work-sub { display: flex; align-items: flex-end; gap: 10px;   /* the words and the fish share one bottom edge, so both sit the same distance above the grid */ margin: auto 0 0;   /* at the foot of the hero column; the gap above it is the heading\'s margin */ font-weight: 500; font-size: calc(var(--sub-base, 18px) * var(--step, 1)); line-height: var(--sub-lh, 1.3333); color: var(--sub); }   /* 18/24 at 1730, full strength */
.work-sub .pin { width: calc(var(--sub-base, 18px) * var(--step, 1)); height: calc(var(--sub-base, 18px) * var(--step, 1)); display: block; margin-bottom: 3px; }   /* level with the x-height, as it was when centred */
/* fish tile: a 77px box holding a 68.8px tilted tile, at the right end of the subtitle's row (it is the row's last flex item), scaled with the
   canvas (--k, window / 1730, set by the page script). The Craft page hangs the same tile under its heading instead (css/craft.css). */
.hero-fish { position: relative; margin-left: auto; align-self: flex-end; flex: none; width: 46px; height: 46px; display: flex; align-items: center; justify-content: center;   /* at the row's right end, the box the tile's own size: its right edge is the content's edge, its foot the row's */
  transform: scale(var(--k, 1)); transform-origin: 100% 100%; }
.hero-fish-tile { display: block; width: 46px; height: 46px; box-sizing: border-box; overflow: hidden; background: #000;
  border: 0; border-radius: 4px; box-shadow: none;   /* a plain square, barely rounded, no tilt, no shadow */
  opacity: 0; filter: none; animation: fishIn .7s ease-out 1.1s both; }
.hero-fish-tile img { width: 100%; height: 100%; object-fit: cover; display: block; transform: scale(1.22) translate(-1%, -6%); }
/* below 1024px the paragraph runs to four or five lines: hang the tile under the subtitle instead of at a fixed height */
@keyframes fishIn { 0% { opacity: 0; } 100% { opacity: 1; } }   /* opacity only: a blur filter leaves the rotated tile rasterised soft */
@media (prefers-reduced-motion: reduce) { .hero-fish-tile { opacity: 1; animation: none !important; } }

/* ---- Project cards (Figma frame 2147236915). The page's own script lays them out on the sliding plane; see tools/canvas/index.template.html ---- */
.work-card { position: absolute; height: 500px; box-sizing: border-box; background: var(--card); border-radius: 40px;
  border: 2px solid rgba(255,255,255,.6);
  /* Figma: drop shadow 0 6 14.7 #00000033 + inner shadow 0 0 17.3 #FFFFFF66 */
  box-shadow: 0 1px 2px rgba(0,0,0,.04), 0 6px 14.7px -1px rgba(0,0,0,.18), 0 8px 24px -8px rgba(0,0,0,.06), inset 0 0 17.3px 0 rgba(255,255,255,.4); }
.work-card { overflow: hidden; will-change: transform, box-shadow; transform-origin: 50% 60%;
  /* leaving: settle back with a plain ease */
  transition: transform .6s ease, box-shadow .8s ease; }
/* entering: quicker ease-out so the lift feels responsive, shadow trails slightly behind */
.work-card:hover { transition: transform .5s cubic-bezier(.22,1,.36,1), box-shadow .7s cubic-bezier(.22,1,.36,1) .04s; }
/* hover: slight lift, shadow deepens with it */
/* hover: the card comes toward you. slight scale + lift, and a three-layer shadow: tight contact shadow,
   mid penumbra, and a wide soft ambient shadow that spreads as the card gets further from the page */
.work-card:hover { transform: translateY(-6px) scale(1.025);
  box-shadow: 0 2px 4px rgba(0,0,0,.05), 0 12px 24px -4px rgba(0,0,0,.12), 0 32px 64px -8px rgba(0,0,0,.20), inset 0 0 17.3px 0 rgba(255,255,255,.4); }
.work-card.has-cover:hover { box-shadow: 0 2px 4px rgba(0,0,0,.05), 0 12px 24px -4px rgba(0,0,0,.12), 0 32px 64px -8px rgba(0,0,0,.20); }
.work-card:hover { z-index: 2; }
@media (prefers-reduced-motion: reduce) { .work-card { transition: none; } .work-card:hover { transform: none; } }
/* cover exports from Figma already carry the 2px white edge and inner glow, so the image sits over the CSS border */
.work-card.has-cover { background: transparent; border-color: transparent; box-shadow: 0 1px 2px rgba(0,0,0,.04), 0 6px 14.7px -1px rgba(0,0,0,.18), 0 8px 24px -8px rgba(0,0,0,.06); }
.work-card.has-cover img.cover { position: absolute; inset: -2px; width: calc(100% + 4px); height: calc(100% + 4px); object-fit: cover; display: block; }

/* ---- Card hover banner (Figma 169:18957 / row 169:21980): 86px band at the bottom, progressive blur 0 -> 14.2px,
        white 20% -> 0 gradient, icon 46px + 15px gap + text column (4px gap): title 22/20 semibold, subtitle 15/18 medium @80% ---- */
.card-meta { position: absolute; left: -2px; right: -2px; bottom: -2px; min-height: 86px; box-sizing: border-box; padding: 20px 25px; display: flex; align-items: center; }
.work-card.knoll .card-meta { min-height: 52px; padding: 3px 25px; }
.card-blur { position: absolute; inset: 0; pointer-events: none; }
.card-blur::before { content: ""; position: absolute; inset: 0; background: linear-gradient(to top, rgba(255,255,255,.2), rgba(255,255,255,0)); opacity: 0; transition: opacity .45s ease; }
.card-blur i { position: absolute; inset: 0; opacity: 0; transition: opacity .45s ease; }
/* four bands, radii compensated for compounding so the effective blur runs ~3.5 / 7.1 / 10.7 / 14.2 top to bottom */
.card-blur i:nth-child(1) { -webkit-backdrop-filter: blur(3.55px); backdrop-filter: blur(3.55px); -webkit-mask-image: linear-gradient(to bottom, rgba(0,0,0,0) 0%, #000 25%, #000 50%, rgba(0,0,0,0) 75%); mask-image: linear-gradient(to bottom, rgba(0,0,0,0) 0%, #000 25%, #000 50%, rgba(0,0,0,0) 75%); }
.card-blur i:nth-child(2) { -webkit-backdrop-filter: blur(6.15px); backdrop-filter: blur(6.15px); -webkit-mask-image: linear-gradient(to bottom, rgba(0,0,0,0) 25%, #000 50%, #000 75%, rgba(0,0,0,0) 100%); mask-image: linear-gradient(to bottom, rgba(0,0,0,0) 25%, #000 50%, #000 75%, rgba(0,0,0,0) 100%); }
.card-blur i:nth-child(3) { -webkit-backdrop-filter: blur(8.7px); backdrop-filter: blur(8.7px); -webkit-mask-image: linear-gradient(to bottom, rgba(0,0,0,0) 50%, #000 75%, #000 100%); mask-image: linear-gradient(to bottom, rgba(0,0,0,0) 50%, #000 75%, #000 100%); }
.card-blur i:nth-child(4) { -webkit-backdrop-filter: blur(11.2px); backdrop-filter: blur(11.2px); -webkit-mask-image: linear-gradient(to bottom, rgba(0,0,0,0) 70%, #000 100%); mask-image: linear-gradient(to bottom, rgba(0,0,0,0) 70%, #000 100%); }
.card-row { position: relative; z-index: 2; display: flex; align-items: center; gap: 15px; min-width: 0; }
.card-icon { flex: none; width: 46px; height: 46px; display: block; object-fit: contain; }
.card-text { display: flex; flex-direction: column; justify-content: center; gap: 4px; min-width: 0; opacity: 0; transform: translateY(6px);
  transition: opacity .4s ease, transform .55s cubic-bezier(.22,1,.36,1); }
.card-title, .card-sub { margin: 0; font-family: var(--ui-font); overflow: visible; white-space: nowrap; }
.card-title { font-weight: 600; font-size: 22px; line-height: 20px; color: var(--t); }
/* the year in the top corner of every card: the nav tab's type at the nav's size on screen (the canvas scales its cards by --k, so the size is
   divided back out), the card's own title colour, inset as the banner is, and only under the pointer, as the banner's words are */
.card-year { position: absolute; top: 22px; right: 25px; z-index: 3; margin: 0; font-family: var(--ui-font); font-weight: 500; font-size: calc(12px / var(--k, 1)); line-height: calc(16px / var(--k, 1)); letter-spacing: 0; color: var(--t, #000); opacity: 0; pointer-events: none; transition: opacity .4s ease; }
.work-card:hover .card-year, .work-card.is-hover .card-year, .work-card.is-open-card .card-year { opacity: .9; }
@media (hover: none) { .card-year { opacity: .9; } }
.card-sub { font-weight: 500; font-size: 15px; line-height: 18px; color: var(--s); opacity: .8; }
.work-card:hover .card-blur::before, .work-card:hover .card-blur i, .work-card.is-hover .card-blur::before, .work-card.is-hover .card-blur i { opacity: 1; }
.work-card:hover .card-text, .work-card.is-hover .card-text { opacity: 1; transform: translateY(0); }
@media (hover: none) { .card-blur::before, .card-blur i, .card-text { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .card-text { transition: none; } }
@media (max-width: 767px) {
  :root { --gutter: 16px; }
  .work-hero { padding-top: 84px; }
  .work-hero h1 { font-size: 26px; line-height: 34px; }
  .work-hero { min-height: 0; } .work-hero h1 { margin-bottom: 40px; }
  .work-sub { font-size: 15px; line-height: 22px; gap: 6px; }
  .work-sub .pin { width: 16px; height: 16px; }
  .hero-fish { width: 34px; height: 34px; transform: none; }
  .hero-fish-tile { width: 34px; height: 34px; border-radius: 4px; }
}
