/* /our-work/ only (loaded by templates/portfolio.j2), on the v2 tokens (sitewide restyle 2026-10-21). Motion numbers and their
   sources: DESIGN.md "Portfolio (/our-work/)". Every rule is scoped under .pf so it cannot leak into other pages. */

/* ---------- filter bar: sticky at the top, chips are radio labels; the fieldset legend is screen-reader only, the
   heading under the bar names it for everyone else ---------- */
.pf { position: relative; padding: 0 0 100px; background: var(--bg); }
.pf-bar { position: sticky; top: var(--pf-top, 0px); transition: top 420ms var(--ease); z-index: 30; background: color-mix(in srgb, var(--bg) 90%, transparent); border-block: 1px solid var(--line); -webkit-backdrop-filter: blur(14px); backdrop-filter: blur(14px); }
.pf-bar fieldset { border: 0; margin: 0; padding: 14px 0; min-width: 0; display: flex; align-items: center; gap: 18px; }
.pf-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.pf-chips input { position: absolute; opacity: 0; width: 1px; height: 1px; pointer-events: none; }
.pf-chips label { display: inline-flex; align-items: center; gap: 8px; min-height: 42px; padding: 0 16px; cursor: pointer; user-select: none; font: 700 14px/1.2 var(--f-head); color: var(--ink-2); background: var(--surface); box-shadow: inset 0 0 0 1px var(--line-2);
  clip-path: polygon(8px 0, 100% 0, 100% calc(100% - 8px), calc(100% - 8px) 100%, 0 100%, 0 8px);
  transition: background-color 100ms var(--ease), color 100ms var(--ease), transform var(--t-quick) var(--ease); }
.pf-chips label .n { font-size: 12px; color: var(--muted); }
.pf-chips label:hover { background: color-mix(in srgb, var(--accent) 10%, var(--surface)); }
.pf-chips label:active { transform: scale(.97); }
.pf-chips input:checked + label { background: var(--accent); color: #0A1428; box-shadow: none; }
.pf-chips input:checked + label .n { color: #0A1428; opacity: .7; }
.pf-chips input:focus-visible + label { outline: 2px solid var(--accent-ink); outline-offset: 3px; }

/* ---------- grid ---------- */
.pf-head { scroll-margin-top: 96px; display: flex; justify-content: space-between; align-items: baseline; gap: 24px; margin: 72px 0 44px; }
.pf-head h2 { font-size: clamp(28px, 3.2vw, 42px); }
.pf-count { color: var(--muted); font-size: 15px; white-space: nowrap; }
.pf-grid { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 76px 56px; }
.pf-card[hidden] { display: none !important; }
.pf-card figure { margin: 0; }
.pf .dev { position: relative; padding: 38px 34px 44px; background: var(--stage); box-shadow: inset 0 0 0 1px var(--line); isolation: isolate; --c: 32px;
  clip-path: polygon(var(--c) 0, 100% 0, 100% calc(100% - var(--c)), calc(100% - var(--c)) 100%, 0 100%, 0 var(--c)); }
.pf .dev::after { content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none; opacity: 0; transition: opacity 100ms; background: radial-gradient(360px circle at var(--mx, 50%) var(--my, 30%), rgba(0, 187, 255, .18), transparent 62%); }
.pf .dev:hover::after { opacity: 1; }
.pf .laptop .screen { aspect-ratio: 16 / 10; }
.pf .laptop .screen img { transform-origin: 50% 0; }
.pf .dev .xphone { position: absolute; right: 26px; bottom: 18px; width: 18%; aspect-ratio: 390 / 844; border-width: 4px; border-radius: 18px; }
.pf .dev .xphone::before { top: 4px; width: 34%; height: 6px; }
.pf .linkcard { aspect-ratio: 16 / 10; }
.pf-info { margin-top: 30px; max-width: 48ch; }
.pf-info h3 { font: 800 clamp(22px, 2vw, 27px)/1.2 var(--f-head); letter-spacing: -.02em; }
.pf-meta { margin-top: 6px; font: 700 13px/1.4 var(--f-head); letter-spacing: .06em; text-transform: uppercase; color: var(--muted); }
.pf-meta span { margin: 0 4px; }
.pf-did { margin-top: 12px; color: var(--ink-2); font-size: 16px; line-height: 1.6; }
.pf-links { margin-top: 18px; display: flex; flex-wrap: wrap; gap: 8px 24px; }
.pf-links a { display: inline-flex; align-items: center; gap: 8px; font: 700 15px/1.2 var(--f-head); color: var(--accent-ink); text-decoration: none; }
.pf-links .arr { width: 16px; height: 16px; transition: transform 240ms var(--ease); }
.pf-links a:hover .arr { transform: translateX(6px); }
.pf-note { margin-top: 80px; }
.js .pf .reveal.pf-shown { opacity: 1; transform: none; }

/* links under the "included" rows */
.pf-more { list-style: none; margin: 40px 0 0; padding: 0; display: flex; flex-wrap: wrap; gap: 12px 32px; }
.pf-more .tlink { margin-top: 0; }

/* ---------- scroll layer (desktop, motion allowed, browsers with scroll-driven animations) ----------
   The phone drifts against the laptop as the card crosses the viewport; the laptop screenshot settles from 1.04 to 1 while
   the card enters. `translate` and `scale` are separate properties, so they never fight the reveal or the hover lift. */
@media (min-width: 981px) and (prefers-reduced-motion: no-preference) {
  @supports (animation-timeline: view()) {
    .pf .dev .xphone { animation: pf-drift linear both; animation-timeline: view(); animation-range: cover 0% cover 100%; }
    .pf .laptop .screen img { animation: pf-settle linear both; animation-timeline: view(); animation-range: entry 0% cover 45%; }
  }
}
@keyframes pf-drift { from { translate: 0 22px; } to { translate: 0 -22px; } }
@keyframes pf-settle { from { scale: 1.04; } to { scale: 1; } }

@media (max-width: 980px) {
  .pf-bar fieldset { padding: 10px 0; gap: 0; }
  .pf-chips { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; margin: 0 -16px; padding: 4px 16px; scroll-padding-inline: 16px; }
  .pf-chips::-webkit-scrollbar { display: none; }
  .pf-chips label { flex: none; }
  .pf-head { flex-direction: column; gap: 8px; margin: 48px 0 32px; }
  .pf-grid { grid-template-columns: 1fr; gap: 56px; }
  .pf .dev { padding: 26px 20px 32px; }
  .pf .dev .xphone { width: 22%; right: 16px; bottom: 12px; }
  .pf-info { margin-top: 24px; }
  .pf-note { margin-top: 56px; }
  .pf { padding-bottom: 72px; }
}
@media (prefers-reduced-motion: reduce) {
  .pf .dev .xphone, .pf .laptop .screen img { animation: none; }
}


/* =====================================================================================================================
   Round 6: the project ring (hero of the page), premium filter bar, case-study callouts. Spec: DESIGN.md "/our-work/ hero".
   ===================================================================================================================== */
.ph.pf-hero { padding-bottom: var(--sp-6); }
.pr { position: relative; padding: var(--sp-8) 0 var(--sp-8); background: var(--bg); overflow-x: clip; }
/* no JS: the grid only. JS on: the stage keeps its height from the first paint (no layout shift) and the grid goes away; reduced motion: grid again */
.pr .pr-stage, .pr .pr-foot { display: none; }
.js .pr .pr-stage { display: block; } .js .pr .pr-foot { display: grid; } .js .pr .pr-fallback { display: none; }
@media (prefers-reduced-motion: reduce) { .js .pr .pr-stage, .js .pr .pr-foot { display: none; } .js .pr .pr-fallback { display: block; } }
.pr-ring { visibility: hidden; } .pr-css .pr-ring, .pr-strip .pr-ring { visibility: visible; }
.pr-fallback .pr-grid { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--grid-gap); }
.pr-grid a { display: grid; gap: 6px; text-decoration: none; color: var(--ink); }
.pr-grid img { width: 100%; aspect-ratio: 16 / 10; object-fit: cover; object-position: top; border-radius: 10px; box-shadow: 0 14px 30px -18px rgba(10, 20, 40, .5); }
.pr-grid b { font: 700 16px/1.2 var(--f-head); } .pr-grid span { font-size: 13px; color: var(--muted); }
.pr-stage { position: relative; height: clamp(400px, 50vw, 700px); outline-offset: -6px; touch-action: pan-y; cursor: grab; -webkit-user-select: none; user-select: none; }
.pr-stage.grab { cursor: grabbing; } .pr-stage.hov { cursor: pointer; }
.pr-cv { position: absolute; inset: 0; width: 100%; height: 100%; display: none; }
.pr-gl .pr-cv { display: block; } .pr-gl .pr-ring { display: none; }
.pr-ring { list-style: none; margin: 0; padding: 0; }
.pr-c img { display: block; width: 100%; aspect-ratio: 16 / 10; height: auto; object-fit: cover; object-position: top; border-radius: 14px; box-shadow: 0 24px 50px -24px rgba(10, 20, 40, .55); }
/* tier 2: the same cards on a CSS 3D ring */
.pr-css .pr-stage { perspective: 1600px; perspective-origin: 50% 30%; overflow: hidden; }
.pr-css .pr-ring { position: absolute; left: 50%; top: 52%; width: 0; height: 0; transform-style: preserve-3d; will-change: transform; }
.pr-css .pr-c { position: absolute; width: var(--cw, 300px); left: calc(var(--cw, 300px) * -.5); top: calc(var(--cw, 300px) * -.31); backface-visibility: hidden; transition: filter 160ms var(--ease); filter: saturate(.92) brightness(.93); }
.pr-css .pr-c.is-f { filter: none; } .pr-css .pr-c.is-h img { box-shadow: 0 0 0 2px var(--cyan), 0 30px 54px -22px rgba(0, 150, 230, .6); }
/* tier 3: the curved strip on phones */
.pr-strip .pr-stage { height: auto; perspective: 900px; cursor: auto; touch-action: auto; }
.pr-strip .pr-ring { display: flex; gap: 10px; overflow-x: auto; scroll-snap-type: x mandatory; padding: var(--sp-4) calc(50% - 34vw); scrollbar-width: none; transform-style: preserve-3d; }
.pr-strip .pr-ring::-webkit-scrollbar { display: none; }
.pr-strip .pr-c { flex: 0 0 68vw; scroll-snap-align: center; transform: rotateY(var(--ry, 0deg)) scale(var(--sc, 1)); opacity: var(--op, 1); }
.pr-strip { padding-top: var(--sp-8); }
/* caption + controls */
.pr-foot { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: var(--sp-7); align-items: end; margin-top: var(--sp-7); }
.pr-cap { position: relative; min-height: 168px; max-width: 560px; }
.pr-num { font: 700 12px/1 var(--f-head); letter-spacing: .2em; color: var(--muted); margin-bottom: var(--sp-3); }
.pr-name { font: 800 clamp(26px, 2.6vw, 36px)/1.1 var(--f-head); letter-spacing: -.025em; }
.pr-meta { margin-top: var(--sp-2); font: 700 13px/1.4 var(--f-head); letter-spacing: .06em; text-transform: uppercase; color: var(--muted); }
.pr-did { margin-top: var(--sp-3); color: var(--ink-2); font-size: 16.5px; line-height: 1.55; }
.pr-links { margin-top: var(--sp-4); display: flex; flex-wrap: wrap; gap: var(--sp-2) var(--sp-5); }
.pr-links a { display: inline-flex; align-items: center; gap: 8px; font: 700 15px/1.2 var(--f-head); color: var(--accent-ink); text-decoration: none; }
.pr-links .arr { width: 16px; height: 16px; transition: transform 240ms var(--ease); } .pr-links a:hover .arr { transform: translateX(6px); }
.pr-px { position: absolute; inset: -8px; z-index: 3; display: grid; grid-template-columns: repeat(12, 1fr); grid-auto-rows: 1fr; pointer-events: none; opacity: 0; }
.pr-px i { background: var(--bg); }
.pr-cap.swap .pr-px { opacity: 1; }
.pr-cap.swap .pr-px i { animation: prPx 260ms var(--ease) var(--d, 0ms) both; }
.pr-cap.swap .pr-name, .pr-cap.swap .pr-meta, .pr-cap.swap .pr-did, .pr-cap.swap .pr-links { animation: prIn 220ms var(--ease) 90ms both; }
@keyframes prPx { from { opacity: 1; } to { opacity: 0; } }
@keyframes prIn { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
.pr-ctl { display: grid; justify-items: end; gap: var(--sp-4); }
.pr-btns { display: flex; gap: var(--sp-3); }
.pr-b { --c: 12px; position: relative; display: grid; place-items: center; width: 54px; height: 54px; padding: 0; border: 0; cursor: pointer; background: var(--ink); color: var(--bg);
  clip-path: polygon(var(--c) 0, 100% 0, 100% calc(100% - var(--c)), calc(100% - var(--c)) 100%, 0 100%, 0 var(--c)); transition: background-color 100ms var(--ease), transform 160ms var(--ease); }
.pr-b:hover { background: var(--accent); color: #0A1428; } .pr-b:active { transform: scale(.94); }
.pr-b .arr { width: 20px; height: 20px; } .pr-b[data-pr-prev] .arr { transform: rotate(180deg); }
.pr-hint { max-width: 36ch; text-align: right; font-size: 13.5px; color: var(--muted); }
@media (max-width: 980px) {
  .pr { padding: var(--sp-8) 0 var(--sp-7); }
  .pr-fallback .pr-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .pr-foot { grid-template-columns: minmax(0, 1fr); gap: var(--sp-5); margin-top: var(--sp-5); }
  .pr-ctl { justify-items: start; grid-template-columns: auto 1fr; align-items: center; } .pr-hint { text-align: left; }
  .pr-cap { min-height: 190px; }
}
/* premium filter chips: one accent block slides to the chosen chip (portfolio.js sets --ix --iy --iw --ih) */
@media (min-width: 981px) {
  .pf-chips { position: relative; }
  .pf-chips.pf-ix::before { content: ""; position: absolute; z-index: 0; left: 0; top: 0; width: var(--iw, 0); height: var(--ih, 42px); transform: translate(var(--ix, 0), var(--iy, 0)); background: var(--accent);
    clip-path: polygon(8px 0, 100% 0, 100% calc(100% - 8px), calc(100% - 8px) 100%, 0 100%, 0 8px); transition: transform 280ms var(--ease), width 280ms var(--ease); }
  .pf-chips.pf-ix label { position: relative; z-index: 1; }
  .pf-chips.pf-ix input:checked + label { background: transparent; }
}
/* case-study callout on a card */
.pf-links .pf-cs { padding: 7px 12px; color: var(--ink); background: color-mix(in srgb, var(--accent) 12%, var(--surface)); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 45%, transparent);
  clip-path: polygon(7px 0, 100% 0, 100% calc(100% - 7px), calc(100% - 7px) 100%, 0 100%, 0 7px); }
.pf-links .pf-cs::before { content: ""; width: 7px; height: 7px; background: var(--accent); }
