/* Portfolio - page components on top of the shared theme (style.css). */

/* =========================================================
   HOME
   ========================================================= */

/* ---------- Hero (template: 70vh, content pinned to the bottom, huge name + intro) ---------- */
#hero{min-height:88vh; min-height:88svh; display:flex; flex-direction:column; justify-content:flex-end; padding:120px var(--gutter) 30px;}
.hero-tag{font-weight:600; color:var(--ink-dim); margin-bottom:14px;}
.hero-name{font-size:clamp(56px,11.4vw,180px); font-weight:700; letter-spacing:-.065em; line-height:.86; cursor:default; --rise:.6em; --step:45ms; --delay:150ms;}
.hero-row{display:grid; grid-template-columns:.7fr .5fr; gap:20px; align-items:end; margin-top:36px;}
.hero-tagline{font-size:clamp(18px,1.9vw,25px); font-weight:600; letter-spacing:-.04em; line-height:1.15; max-width:620px; --rise:20px; --step:9ms; --delay:900ms;}
.hero-note{color:var(--ink-dim); font-weight:600; margin-top:14px;}
.hero-side{display:flex; flex-direction:column; align-items:flex-start; gap:22px;}
.hero-cta{display:flex; gap:10px; flex-wrap:wrap;}
.scroll-cue{display:flex; justify-content:space-between; align-items:center; margin-top:60px; font-weight:600; color:var(--ink-dim);}
.scroll-cue .cue-line{flex:1; margin:0 20px;}
.cue-arrow{animation:cue 2.4s var(--ease-roll) infinite;}
@keyframes cue{0%,100%{transform:translateY(-3px); opacity:.5;} 50%{transform:translateY(3px); opacity:1;}}
@media (max-width:809px){
  #hero{padding:110px 15px 24px; min-height:92svh;}
  .hero-row{grid-template-columns:1fr; gap:28px; margin-top:24px;}
}

/* ---------- Selected work: full-bleed cards that stack while scrolling ----------
   Each card is sticky; the next one slides over it and the covered one scales down and dims
   (scroll-linked in js/main.js). Text column is sticky too, as in the template. */
#work{padding:0 0 100px;}
.work-list{position:relative;}
.work{position:sticky; top:0; height:100vh; height:100svh; overflow:hidden; display:block; color:#fff; background:#000;}
.work-media{position:absolute; inset:0; transform-origin:50% 0; will-change:transform, opacity; opacity:var(--o, .6); transform:scale(var(--s, 1));}
.work-media .ph{position:absolute; inset:0;}
.work-media::after{content:""; position:absolute; inset:0; background:linear-gradient(180deg, rgba(0,0,0,.55) 0%, rgba(0,0,0,0) 30%, rgba(0,0,0,0) 55%, rgba(0,0,0,.75) 100%); z-index:2;}
.work-text{position:absolute; inset:0; z-index:3; display:grid; grid-template-columns:1fr 1fr; gap:20px; padding:96px var(--gutter) 30px; pointer-events:none;}
.work-title{display:flex; flex-direction:column; gap:3px;}
.work-title h3{font-size:25px; letter-spacing:-.04em;}
.work-title .work-meta{display:flex; gap:20px; font-size:25px; font-weight:600; letter-spacing:-.04em; color:var(--ink-dim);}
.work-body{align-self:end; justify-self:end; max-width:460px; pointer-events:auto;}
.work-body p{color:rgba(255,255,255,.75); font-size:15px; line-height:1.5;}
.work-body .tags{margin-top:16px;}
.work-body .btn{margin-top:20px; background:rgba(0,0,0,.35); backdrop-filter:blur(8px); -webkit-backdrop-filter:blur(8px);}
.work-index{position:absolute; right:var(--gutter); top:96px; z-index:3; font-size:25px; font-weight:600; letter-spacing:-.04em; color:var(--ink-dim);}
@media (max-width:809px){
  .work-text{grid-template-columns:1fr; padding:84px 15px 24px; align-content:space-between;}
  .work-title h3, .work-title .work-meta, .work-index{font-size:20px;}
  .work-index{top:84px; right:15px;}
  .work-body{justify-self:start;}
}

/* ---------- Tags / pills ---------- */
.tags{display:flex; gap:6px; flex-wrap:wrap; align-items:center;}
.tag{border:1px solid var(--line); border-radius:999px; padding:4px 10px; font-size:12px; font-weight:600; color:var(--ink-dim); white-space:nowrap;}

/* ---------- Ethos / intro statement (template "Section About") ---------- */
#ethos{padding:150px var(--gutter) 100px; overflow:hidden;}
.ethos-lines{display:flex; flex-direction:column; gap:20px; margin-bottom:20px;}
.ethos-grid{display:grid; grid-template-columns:.5fr 1fr; gap:20px; align-items:start;}
.ethos-statement{font-size:clamp(30px,3.4vw,40px); font-weight:600; letter-spacing:-.045em; line-height:1.08; max-width:860px;}
/* Word highlight on scroll: words go from .2 to 1 opacity as the paragraph crosses the screen */
.ethos-statement .wd{opacity:var(--wo, 1); transition:opacity .15s linear;}
html.js .ethos-statement .wd{--wo:.2;}
.ethos-foot{display:flex; justify-content:space-between; align-items:flex-end; gap:20px; margin-top:60px; flex-wrap:wrap;}
@media (max-width:809px){ #ethos{padding:100px 15px 80px;} .ethos-grid{grid-template-columns:1fr;} }

/* ---------- Crafts (template About: numbered rows divided by lines) ---------- */
.crafts{border-top:1px solid var(--line);}
.craft{display:grid; grid-template-columns:.5fr .5fr 1fr; gap:20px; padding:28px 0 34px; border-bottom:1px solid var(--line); align-items:start;}
.craft-num{font-weight:600; color:var(--ink-faint);}
.craft h3{font-size:25px; letter-spacing:-.04em;}
.craft p{color:var(--ink-dim); font-size:16px; max-width:560px;}
.craft .craft-sub{display:block; font-size:14px; font-weight:600; color:var(--ink-faint); margin-top:6px; letter-spacing:var(--track);}
@media (max-width:809px){ .craft{grid-template-columns:1fr; gap:10px;} }

/* ---------- Latest articles: horizontal "journal" slideshow ---------- */
.journal-track{
  display:flex; gap:20px; overflow-x:auto; scroll-snap-type:x mandatory; padding:0 var(--gutter) 10px; scroll-padding-inline:var(--gutter); align-items:flex-start;
  scrollbar-width:none; cursor:grab;
}
.journal-track::-webkit-scrollbar{display:none;}
.journal-track.dragging{cursor:grabbing; scroll-snap-type:none;}
.journal-track .article-card{flex:0 0 clamp(280px,28vw,420px); scroll-snap-align:start;}
.journal-nav{display:flex; gap:8px;}
.journal-nav button{width:38px; height:38px; border-radius:50%; border:1px solid var(--line); background:transparent; color:#fff; cursor:pointer; font-size:16px; transition:border-color .2s ease;}
.journal-nav button:hover{border-color:#fff;}
.journal-head{display:flex; justify-content:space-between; align-items:flex-end; gap:20px; padding:0 var(--gutter); margin-bottom:30px;}
.journal-head h2{font-size:clamp(40px,6vw,84px); letter-spacing:-.06em; line-height:.9;}
.journal-foot{padding:0 var(--gutter); margin-top:30px;}

/* ---------- Article card (shared by Home + Articles; built by js/articles.js) ---------- */
.article-card{
  display:flex; flex-direction:column; gap:12px; text-align:left; width:100%;
  background:none; border:0; padding:0; color:var(--ink); cursor:pointer; font:inherit; letter-spacing:inherit;
}
.article-thumb{position:relative; aspect-ratio:4/3; overflow:hidden; background:var(--surface);}
.article-card:nth-child(3n+2) .article-thumb{aspect-ratio:1/1;}
.article-thumb .ph{position:absolute; inset:0; transition:transform .8s var(--ease-out);}
.article-card:hover .article-thumb .ph{transform:scale(1.05);}
.article-thumb-word{position:absolute; left:18px; right:18px; bottom:14px; z-index:2; font-size:clamp(28px,3vw,44px); font-weight:700; letter-spacing:-.06em; line-height:.9; color:rgba(255,255,255,.9);}
.article-thumb-date{position:absolute; left:18px; top:14px; z-index:2; font-size:12px; font-weight:600; color:var(--ink-dim);}
.article-meta{display:flex; gap:12px; flex-wrap:wrap; font-size:12px; font-weight:600; color:var(--ink-faint);}
.article-card h3{font-size:20px; letter-spacing:-.04em; line-height:1.15;}
.article-card p{color:var(--ink-dim); font-size:14px; display:-webkit-box; -webkit-line-clamp:3; -webkit-box-orient:vertical; overflow:hidden;}
.article-card .tags{margin-top:2px;}
.read-more{font-weight:600; margin-top:4px;}

/* ---------- Contact (template contact page headline) ---------- */
#contact{padding:150px var(--gutter);}
.contact-big{--rise:.5em; --step:14ms; font-size:clamp(44px,7vw,110px); font-weight:700; letter-spacing:-.065em; line-height:.9; max-width:1200px;}
.contact-big .dim{color:var(--ink-faint);}
.contact-row{display:grid; grid-template-columns:.5fr 1fr; gap:20px; margin-top:50px; align-items:start;}
.contact-row p{color:var(--ink-dim); font-size:16px; max-width:520px;}
.contact-row .hero-cta{margin-top:24px;}
@media (max-width:809px){ #contact{padding:100px 15px;} .contact-row{grid-template-columns:1fr;} }

/* ---------- Ocarina (kept from the previous site, redrawn in monochrome) ---------- */
#ocarina{padding:120px var(--gutter);}
.ocarina-grid{display:grid; grid-template-columns:1fr 1fr; gap:60px; align-items:center;}
@media (max-width:900px){ .ocarina-grid{grid-template-columns:1fr; gap:40px;} #ocarina{padding:90px 15px;} }
.instrument{position:relative; display:flex; justify-content:center; padding:40px 0; border:1px solid var(--line-soft);}
.instrument svg{width:min(100%,400px); height:auto;}
.oc-body{fill:var(--surface-2); stroke:var(--line); stroke-width:1.5;}
.hole{fill:#000; stroke:rgba(255,255,255,.25); stroke-width:1; cursor:pointer; transition:fill .15s ease, filter .15s ease;}
.hole:hover{fill:#222;}
.hole.lit{fill:#fff !important; filter:drop-shadow(0 0 10px rgba(255,255,255,.9));}
.hole:focus-visible{outline:1px solid #fff; outline-offset:3px;}
.note-caption{text-align:center; margin-top:16px; font-weight:600; color:var(--ink-dim); min-height:1.5em;}
.ocarina-copy h2{font-size:clamp(30px,3.4vw,40px); margin-top:10px;}
.ocarina-copy > p{color:var(--ink-dim); font-size:16px; margin-top:16px; max-width:560px;}
.melody-row{display:flex; gap:8px; flex-wrap:wrap; margin-top:28px;}
.melody-btn{border:1px solid var(--line); background:transparent; color:#fff; padding:9px 14px; border-radius:999px; cursor:pointer; font-size:13px; font-weight:600; transition:background .25s ease, color .25s ease, border-color .25s ease;}
.melody-btn:hover{background:#fff; color:#000; border-color:#fff;}
.ocarina-hint{font-size:13px; color:var(--ink-faint); margin-top:16px;}

/* =========================================================
   INNER PAGES
   ========================================================= */
.page-hero{padding:170px var(--gutter) 60px;}
.page-hero h1{font-size:clamp(56px,11vw,170px); font-weight:700; letter-spacing:-.065em; line-height:.86; --rise:.6em; --step:40ms; --delay:100ms;}
.page-hero-row{display:grid; grid-template-columns:.5fr 1fr; gap:20px; margin-top:40px; align-items:start;}
.page-hero .lede{color:var(--ink-dim); font-size:16px; max-width:620px;}
@media (max-width:809px){ .page-hero{padding:120px 15px 40px;} .page-hero-row{grid-template-columns:1fr; margin-top:24px;} }

/* ---------- Articles page: search, filters, grid ---------- */
.article-controls{display:flex; gap:16px; flex-wrap:wrap; align-items:center; justify-content:space-between; padding:20px 0; margin-bottom:20px;}
.article-controls input{
  flex:0 1 340px; padding:12px 0; border:0; border-bottom:1px solid var(--line); border-radius:0;
  background:transparent; color:#fff; font:inherit; font-weight:600; font-size:16px; letter-spacing:inherit;
}
.article-controls input::placeholder{color:var(--ink-faint);}
.article-controls input:focus{outline:none; border-bottom-color:#fff;}
.chips{display:flex; gap:6px; flex-wrap:wrap;}
.chip{
  border:1px solid var(--line); background:transparent; color:var(--ink-dim); border-radius:999px;
  padding:7px 13px; font-size:13px; font-weight:600; cursor:pointer; transition:border-color .2s ease, background .2s ease, color .2s ease;
}
.chip:hover{border-color:#fff; color:#fff;}
.chip.active{background:#fff; border-color:#fff; color:#000;}
#articleCount{font-size:13px; font-weight:600; margin-bottom:30px;}
.articles-grid{display:grid; grid-template-columns:repeat(3,1fr); gap:60px 20px;}
@media (max-width:1100px){ .articles-grid{grid-template-columns:repeat(2,1fr);} }
@media (max-width:640px){ .articles-grid{grid-template-columns:1fr;} }
.articles-grid .article-card:nth-child(3n+2) .article-thumb{aspect-ratio:4/3;}

/* ---------- Article reader: "Poké modal" (animation in js/poke-modal.js) ----------
   Same animation as before (circle pops in, spins into a rounded square, springs open),
   recoloured in black and white. Sizes below are the OPEN state; JS animates from the small one. */
.reader[hidden]{display:none;}
.reader{position:fixed; inset:0; z-index:120; overflow:hidden;}
.reader-backdrop{position:absolute; inset:0; background:rgba(0,0,0,.72); backdrop-filter:blur(6px); -webkit-backdrop-filter:blur(6px);}
.poke-frame, .poke-inner, .poke-icon{position:absolute; left:50%; top:50%; transform:translate(-50%,-50%);}
.poke-frame{background:#fff; box-shadow:0 30px 80px -20px rgba(0,0,0,.8); will-change:transform, width, height;}
.poke-band{position:absolute; inset:5px; background:linear-gradient(160deg, #2a2a2a, #111 50%, #000);}
.poke-inner{background:#0a0a0a; color:#fff; border-radius:15px; overflow:hidden; display:flex; flex-direction:column; will-change:transform, width, height, opacity;}
.poke-scroll{flex:1; overflow-y:auto; overscroll-behavior:contain; padding:64px clamp(20px,6vw,64px) 56px; scrollbar-width:none;}
.poke-scroll::-webkit-scrollbar{display:none;}
.poke-scroll:focus{outline:none;}
.poke-scroll:focus-visible{outline:1px solid #fff; outline-offset:-4px; border-radius:14px;}
.poke-content{max-width:680px; margin:0 auto;}
.poke-icon{
  width:50px; height:50px; border-radius:50%; background:#fff; color:#000;
  display:flex; align-items:center; justify-content:center;
  box-shadow:0 0 0 4px #000 inset; pointer-events:none; z-index:2;
}
.poke-icon svg{width:34px; height:34px; display:block;}
.reader-close{
  position:absolute; top:14px; right:14px; z-index:3; width:40px; height:40px; border-radius:50%;
  border:1px solid var(--line); background:#0a0a0a; color:#fff; font-size:1.3rem; cursor:pointer; transition:border-color .2s ease;
}
.reader-close:hover{border-color:#fff;}
.reader h2{font-size:clamp(28px,3.6vw,44px); letter-spacing:-.05em; margin:12px 0 14px;}
#readerMeta{font-size:13px; font-weight:600;}
.reader-body{margin-top:32px; font-size:16px; line-height:1.65; letter-spacing:-.01em; color:rgba(255,255,255,.82);}
.reader-body p{margin:0 0 1.1em;}
.reader-body strong{color:#fff;}
.reader-body a{text-decoration:underline; text-underline-offset:3px;}
.reader-body h3{font-size:22px; color:#fff; margin:1.8em 0 .6em;}
.reader-body ul, .reader-body ol{padding-left:1.2em; margin:0 0 1.1em;}
.reader-body li + li{margin-top:.3em;}
.reader-body code{font-family:ui-monospace,Consolas,monospace; font-size:.86em; background:var(--surface-2); padding:.1em .35em; border-radius:4px;}
.reader-body pre{background:var(--surface); border:1px solid var(--line-soft); padding:16px; border-radius:8px; overflow-x:auto; font-size:13px; line-height:1.5;}
.reader-body pre code{background:none; padding:0;}

/* ---------- AI Chat ----------
   Same grid as the other pages: labels and suggestions on the left (.5fr), the conversation on the right.
   No boxed "app" window: messages are rows separated by thin lines, the input is an underlined field
   that stays at the bottom of the screen while the conversation grows with the page. */
.chat-section{padding:0 var(--gutter) 120px;}
.chat-layout{display:grid; grid-template-columns:.5fr 1fr; gap:20px; align-items:start; padding-top:40px;}
@media (max-width:900px){
  .chat-section{padding:0 15px 80px;}
  .chat-layout{grid-template-columns:1fr; gap:60px;}
  .chat-box{order:-1;}
}
.chat-side{display:flex; flex-direction:column; gap:50px; position:sticky; top:110px;}
@media (max-width:900px){ .chat-side{position:static;} }
.side-block .eyebrow{margin-bottom:14px;}
.side-text{font-size:14px; color:var(--ink-dim); max-width:340px;}
.side-text + .side-text{margin-top:10px;}
.side-text a{color:#fff; text-decoration:underline; text-underline-offset:3px;}

/* Suggestions: large dim links, like the footer navigation */
.suggestions{display:flex; flex-direction:column; align-items:flex-start; gap:4px;}
.suggestions .chip{
  border:0; background:none; padding:0; border-radius:0; cursor:pointer; text-align:left;
  font-size:24px; font-weight:600; letter-spacing:-.04em; color:var(--ink-faint); transition:color .25s ease;
}
.suggestions .chip:hover, .suggestions .chip:focus-visible{color:#fff; background:none;}
@media (max-width:809px){ .suggestions .chip{font-size:20px;} }

/* Header row of the conversation: status dot, name, quota */
.chat-head{display:flex; align-items:center; gap:10px; flex-wrap:wrap; padding-bottom:20px; font-weight:600;}
.chat-head .status{--led:#777; width:7px; height:7px; border-radius:50%; flex:none; background:var(--led);}
.chat-head .status[data-state="checking"]{animation:led-pulse 1.2s ease-in-out infinite;}
.chat-head .status[data-state="online"]{--led:var(--live); animation:live 2.2s ease-out infinite;}
.chat-head .status[data-state="offline"]{--led:#ff5a5f;}
@keyframes led-pulse{50%{opacity:.3;}}
.chat-head .note{margin-left:auto; color:var(--ink-faint); font-size:13px;}
#chatQuota:empty, #chatQuota:empty ~ .quota-sep, .quota-sep:has(+ #chatQuota:empty){display:none;}

/* Messages: who on the left, text on the right, thin line above each row */
.chat-log{display:flex; flex-direction:column;}
.msg{
  display:grid; grid-template-columns:110px 1fr; gap:20px; padding:22px 0 26px; border-top:1px solid var(--line-soft);
  animation:msg-in .7s var(--ease) both; scroll-margin-bottom:140px;
}
@keyframes msg-in{from{opacity:0; transform:translateY(24px);} to{opacity:1; transform:none;}}
.msg-who{font-size:13px; font-weight:600; color:var(--ink-faint); padding-top:.35em;}
.msg-body{white-space:pre-wrap; min-width:0; overflow-wrap:anywhere;}
.msg.user .msg-body{font-size:clamp(20px,2vw,25px); font-weight:600; letter-spacing:-.04em; line-height:1.2; color:#fff;}
.msg.bot .msg-body{font-size:16px; line-height:1.6; letter-spacing:-.01em; color:rgba(255,255,255,.82); max-width:720px;}
.msg-body.pending{color:var(--ink-faint);}
.msg-body.pending::after{content:""; display:inline-block; width:.5em; animation:dots 1.2s steps(4) infinite; overflow:hidden; vertical-align:bottom;}
@keyframes dots{0%{content:"";} 25%{content:".";} 50%{content:"..";} 75%{content:"...";}}
@media (max-width:640px){ .msg{grid-template-columns:1fr; gap:6px;} }
/* Rendered Markdown inside bot replies */
.msg-body.md{white-space:normal;}
.msg-body.md > :first-child{margin-top:0;}
.msg-body.md > :last-child{margin-bottom:0;}
.msg-body.md p, .msg-body.md ul, .msg-body.md ol, .msg-body.md pre, .msg-body.md blockquote{margin:0 0 .8em;}
.msg-body.md ul, .msg-body.md ol{padding-left:1.3em;}
.msg-body.md li + li{margin-top:.25em;}
.msg-body.md h1, .msg-body.md h2, .msg-body.md h3, .msg-body.md h4{font-size:18px; color:#fff; margin:1em 0 .4em;}
.msg-body.md strong{font-weight:600; color:#fff;}
.msg-body.md a{color:#fff; text-decoration:underline; text-underline-offset:3px;}
.msg-body.md code{font-family:ui-monospace,Consolas,monospace; font-size:.86em; background:var(--surface-2); padding:.1em .35em; border-radius:4px;}
.msg-body.md pre{background:var(--surface); border:1px solid var(--line-soft); padding:12px 14px; border-radius:8px; overflow-x:auto;}
.msg-body.md pre code{background:none; padding:0;}
.msg-body.md blockquote{border-left:1px solid var(--line); padding-left:.9em; color:var(--ink-dim);}
.msg-body.md table{border-collapse:collapse; font-size:.92em; margin:0 0 .8em;}
.msg-body.md th, .msg-body.md td{border:1px solid var(--line); padding:.35em .7em;}

/* Input: underlined field, sticky at the bottom of the screen */
.chat-form{
  position:sticky; bottom:0; z-index:5; display:flex; align-items:center; gap:14px;
  padding:22px 0 24px; border-top:1px solid var(--line); background:linear-gradient(transparent, #000 22%);
}
.chat-form input{
  flex:1; min-width:0; padding:10px 0; border:0; border-bottom:1px solid var(--line); border-radius:0; background:transparent;
  color:#fff; font:inherit; font-size:clamp(18px,1.8vw,22px); font-weight:600; letter-spacing:-.04em;
  transition:border-color .25s ease;
}
.chat-form input::placeholder{color:var(--ink-faint);}
.chat-form input:focus{outline:none; border-bottom-color:#fff;}
.chat-form input:disabled{opacity:.5;}
@media (max-width:640px){ .chat-form input{font-size:16px; letter-spacing:-.02em;} .chat-form{gap:10px;} }

/* ---------- Language switch (EN / FR) - button injected by js/i18n.js ---------- */
.lang-toggle{
  flex:none; padding:0; border:0; background:none; cursor:pointer; color:#fff;
  font-size:14px; font-weight:600; line-height:1; letter-spacing:var(--track);
  opacity:.6; transition:opacity .2s ease;
}
.lang-toggle:hover{opacity:1;}

/* Hide the page for the split second before French is applied (no flash of English). */
html.i18n-pending body{visibility:hidden;}

/* ---------- Print: the site chrome never prints ---------- */
@media print{
  header, footer, .mobile-menu{display:none !important;}
  html, body{background:#fff; color:#000;}
}

/* ---------- Generative visuals (js/visuals.js) ---------- */
.ph-graph{background:#000;}
.ph-graph::after{display:none;}
.ph canvas{position:absolute; inset:0; z-index:1; display:block;}
.ph-graph .ph-label{z-index:3; color:var(--ink-faint);}

/* ---------- Project cards: main technologies, large, bottom-left (fills the empty column) ---------- */
.work-left{display:flex; flex-direction:column; justify-content:space-between; gap:30px; min-height:0;}
.work-stack .eyebrow{margin-bottom:14px;}
.work-stack ul{list-style:none; margin:0; padding:0;}
.work-stack li{font-size:clamp(34px,4.4vw,68px); font-weight:600; letter-spacing:-.055em; line-height:1; color:#fff;}
.work-stack li + li{margin-top:.06em;}
html.js .work-stack li{opacity:0; transform:translateY(40px); transition:opacity .9s var(--ease), transform .9s var(--ease);}
html.js .work.in-view .work-stack li{opacity:1; transform:none;}
.work-stack li:nth-child(2){transition-delay:.08s;} .work-stack li:nth-child(3){transition-delay:.16s;}
.work-stack li:nth-child(4){transition-delay:.24s;} .work-stack li:nth-child(5){transition-delay:.32s;}
@media (max-width:809px){
  .work-left{gap:10px;}
  .work-stack .eyebrow{display:none;}
  .work-stack ul{display:flex; flex-wrap:wrap; gap:2px 12px;}
  .work-stack li{font-size:16px; letter-spacing:-.03em; color:var(--ink-dim);}
  .work-stack li + li{margin-top:0;}
}
/* Visual caption: top-right under the card number (the bottom-left corner now holds the stack) */
.work .ph-label{left:auto; right:var(--gutter); bottom:auto; top:136px; text-align:right; max-width:260px;}
@media (max-width:809px){ .work .ph-label{right:15px; top:auto; bottom:auto; top:206px;} }

/* ---------- Tech stack marquee (#ethos) ----------
   Full-bleed row of white logos scrolling right to left forever. The track holds the list twice
   (second copy added by js/main.js) and moves by -50%, so the loop has no visible seam.
   Pauses on hover; edges fade out; static, wrapping list for reduced motion or without JS. */
.stack-marquee{
  margin:90px calc(-1 * var(--gutter)) 0; overflow:hidden; padding:26px 0;
  border-top:1px solid var(--line-soft); border-bottom:1px solid var(--line-soft);
  -webkit-mask-image:linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
          mask-image:linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
}
.stack-track{display:flex; width:max-content;}
.stack-track.running{animation:stack-scroll 70s linear infinite;}
.stack-marquee:hover .stack-track{animation-play-state:paused;}
@keyframes stack-scroll{to{transform:translateX(-50%);}}
.stack-list{display:flex; list-style:none; margin:0; padding:0;}
.tech{
  display:flex; align-items:center; gap:14px; padding:0 34px; flex:none;
  font-size:clamp(20px,2vw,28px); font-weight:600; letter-spacing:-.04em; color:rgba(255,255,255,.72);
  transition:color .3s ease;
}
.tech svg, .tech .tech-img{width:1.25em; height:1.25em; flex:none; display:block;}
.tech .tech-img{background-size:contain; background-repeat:no-repeat; background-position:center; filter:brightness(0) invert(1);}
.tech svg, .tech .tech-img{opacity:.9; transition:opacity .3s ease;}
.tech:hover{color:#fff;}
.tech:hover svg, .tech:hover .tech-img{opacity:1;}
@media (prefers-reduced-motion: reduce){
  .stack-marquee{-webkit-mask-image:none; mask-image:none;}
  .stack-list{flex-wrap:wrap; justify-content:center; row-gap:18px; padding:0 var(--gutter);}
}
@media (max-width:809px){
  .stack-marquee{margin:60px -15px 0; padding:20px 0;}
  .tech{padding:0 22px; gap:10px;}
  .stack-track.running{animation-duration:55s;}
}
