/* ============================================================
   Portfolio_DS  .  case.css
   Layout for the four case studies: Tino, DataGuard, Taxmaro,
   RoomReady.

   Loaded after system.css. The case studies run one notch tighter
   than the index pages: h1 to 76px, section rhythm to 96px, mono
   labels at 11px. That is a design decision, so where a selector
   here also appears in index.css the values differ on purpose.

   The last block (.stmt-row, .rail-list, .numbers, .chips,
   .fig-note) belongs to the three generated case studies. Tino does
   not use it yet, and may.
   ============================================================ */

*{box-sizing:border-box}
body{margin:0;background:var(--paper);color:var(--ink);font-family:var(--body);font-size:16px;line-height:1.6;-webkit-font-smoothing:antialiased}
@media (prefers-reduced-motion: reduce){
  *,*::before,*::after{animation-duration:.001ms!important;transition-duration:.001ms!important}
}
h1,h2,h3,h4{font-family:var(--display);font-weight:600;letter-spacing:-.03em;margin:0;text-wrap:balance;line-height:1.04}
.mono{font-family:var(--mono);font-size:11px;letter-spacing:.06em;text-transform:uppercase;font-weight:500}
.navbar{display:flex;align-items:center;gap:14px;height:62px}
.brand{font-family:var(--display);font-weight:600;letter-spacing:-.02em;font-size:15px;color:var(--ink-4)}
@media(max-width:560px){
  .brand{display:none}
}
/* The reading header. At the top of the page it is the plain header plus a call button.
   Once the hero has gone (header.js sets .is-reading) the name gives way to the section
   being read, which opens the list of all of them, and a violet line along the bottom
   edge fills with the page. The call button is violet rather than --btn, which is lime
   in the dark theme and would be a second lime in a viewport that already has one. */
a.brand{transition:color .18s}
a.brand:hover{color:var(--ink)}
.rh-call{margin-left:10px;display:inline-flex;align-items:center;padding:8px 14px;border-radius:100px;background:var(--violet);color:var(--on-violet);font-size:13px;font-weight:600;white-space:nowrap;transition:opacity .2s,background .2s}
.rh-call:hover{background:var(--violet-ink)}
.rh.at-end .rh-call{opacity:0;pointer-events:none;visibility:hidden}
.rh-where{display:none;position:relative;min-width:0;flex:0 1 auto}
.rh.is-reading .brand{display:none}
.rh.is-reading .rh-where{display:block;animation:rh-in .24s ease-out}
@keyframes rh-in{from{opacity:0;transform:translateY(4px)}to{opacity:1;transform:none}}
.rh-btn{
  display:flex;align-items:center;gap:9px;max-width:100%;min-width:0;padding:7px 10px 7px 12px;border-radius:100px;
  border:1px solid var(--line);background:var(--raise);color:var(--ink);cursor:pointer;font:inherit;transition:border-color .18s
}
.rh-btn:hover,.rh-btn[aria-expanded="true"]{border-color:var(--violet)}
.rh-name{font-family:var(--display);font-weight:600;font-size:14px;letter-spacing:-.02em;white-space:nowrap}
.rh-name::after{content:"·";margin-left:9px;color:var(--ink-4)}
.rh-cur{font-size:13px;color:var(--ink-2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0}
.rh-count{font-family:var(--mono);font-size:10px;letter-spacing:.06em;color:var(--ink-4);font-variant-numeric:tabular-nums}
.rh-btn svg{width:12px;height:12px;flex:0 0 auto;fill:none;stroke:var(--ink-3);stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round;transition:transform .18s}
.rh-btn[aria-expanded="true"] svg{transform:rotate(180deg)}
.rh-list{
  position:absolute;top:calc(100% + 8px);left:0;min-width:260px;max-height:min(70vh,440px);overflow:auto;margin:0;padding:6px;list-style:none;
  background:var(--raise);border:1px solid var(--line);border-radius:12px;box-shadow:var(--shadow)
}
.rh-list a{display:flex;align-items:baseline;gap:12px;padding:9px 12px;border-radius:8px;font-size:14px;color:var(--ink-2)}
.rh-list a:hover,.rh-list a:focus-visible{background:var(--paper-2);color:var(--ink)}
.rh-list a[aria-current]{background:var(--violet-tint);color:var(--violet-ink);font-weight:500}
.rh-list .n{font-family:var(--mono);font-size:10px;letter-spacing:.06em;color:var(--ink-4);font-variant-numeric:tabular-nums}
.rh-list a[aria-current] .n{color:var(--violet-ink)}
.rh-bar{position:absolute;left:0;right:0;bottom:-1px;height:2px;pointer-events:none}
.rh-bar i{display:block;height:100%;background:var(--violet);transform:scaleX(0);transform-origin:left center}
/* Where the browser can tie an animation to the scroll position, the line fills on the
   compositor with no script at all; header.js only writes it where this is missing. It
   is the reader's position rather than motion, so it keeps running under reduced
   motion: the duration is pinned to auto against the blanket .001ms rule above. */
@supports (animation-timeline: scroll()){
  .rh-bar i{animation:rh-fill linear both;animation-duration:auto!important;animation-timeline:scroll(root block)}
  @keyframes rh-fill{from{transform:scaleX(0)}to{transform:scaleX(1)}}
}
.sec-head[id]{scroll-margin-top:84px}
@media(max-width:720px){
  .rh-name{display:none}
}
@media(max-width:560px){
  .rh #theme-label{display:none}
  .rh .toggle{padding:8px}
  .rh-call{padding:8px 12px;font-size:12.5px}
  .rh-count{display:none}
  .rh-list{position:fixed;left:var(--pad);right:var(--pad);top:70px;min-width:0}
}
.hero{padding-block:clamp(44px,7vw,84px) clamp(32px,4vw,48px);position:relative;overflow:hidden}
.hero::before{
  content:"";position:absolute;inset:0;pointer-events:none;
  background-image:linear-gradient(90deg,var(--grid-line) 1px,transparent 1px);background-size:calc(100%/12) 100%;
  mask-image:linear-gradient(to bottom,rgba(0,0,0,.8),transparent 72%);
  -webkit-mask-image:linear-gradient(to bottom,rgba(0,0,0,.8),transparent 72%)
}
.hero .shell{position:relative}
.pill{
  display:inline-flex;align-items:center;gap:9px;background:var(--violet-tint);color:var(--violet-ink);
  padding:6px 13px 6px 11px;border-radius:100px;font-family:var(--mono);font-size:10.5px;letter-spacing:.1em;text-transform:uppercase;font-weight:500
}
.pill .dot{width:7px;height:7px;border-radius:50%;background:var(--lime)}
h1.head{margin-top:20px;font-size:clamp(38px,6.6vw,76px);letter-spacing:-.045em;max-width:14ch}
.lede{margin-top:22px;font-size:clamp(16.5px,1.5vw,19px);line-height:1.62;color:var(--ink-2);max-width:54ch}
.lede b{color:var(--ink);font-weight:600}
.meta{margin-top:clamp(34px,4.5vw,52px);display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:22px;border-top:1px solid var(--line);padding-top:20px}
@media(max-width:720px){
  .meta{grid-template-columns:repeat(2,minmax(0,1fr));gap:24px 20px}
}
.meta dt{font-family:var(--mono);font-size:10px;letter-spacing:.1em;text-transform:uppercase;color:var(--ink-4);font-weight:500}
.meta dd{margin:7px 0 0;font-size:15px;font-weight:500;color:var(--ink);line-height:1.35}
.metrics{margin-top:22px;display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:22px;border-top:1px solid var(--line);padding-top:20px}
@media(max-width:560px){
  .metrics{grid-template-columns:1fr;gap:20px}
}
.metrics dt{font-family:var(--mono);font-size:10px;letter-spacing:.1em;text-transform:uppercase;color:var(--ink-4);font-weight:500}
.metrics dd{margin:7px 0 0;font-family:var(--display);font-size:clamp(28px,3.4vw,36px);font-weight:600;letter-spacing:-.038em;line-height:1;font-variant-numeric:tabular-nums}
.metrics div:first-child dd{color:var(--violet)}
.metrics small{display:block;margin-top:6px;font-size:12.5px;color:var(--ink-3);line-height:1.45}
/* Opt-in: a diagram of the idea carries the right of the hero. It sits in a .fig card,
   so its labels are measured on --raise rather than on the field. Outcomes and facts
   follow as two strips, their labels at --ink-3 because this high they sit on the field. */
.hero-diagram{display:grid;grid-template-columns:minmax(0,1fr) minmax(300px,380px);gap:clamp(32px,5vw,72px);align-items:center}
.hero-diagram .lede{max-width:48ch}
.hero-diagram ~ .metrics{margin-top:clamp(36px,4.5vw,56px)}
.hero-diagram ~ .metrics dt{color:var(--ink-3)}
.hero-diagram ~ .meta{margin-top:22px}
@media(max-width:900px){
  .hero-diagram{grid-template-columns:minmax(0,1fr)}
  .hero-diagram .fig{max-width:420px}
}
/* The vocabulary the generated heroes draw with. Tino's ring keeps its own, because
   nothing else is a ring. Violet only: the hero spends its lime on the pill. */
.hero-diagram .fig{margin:0}
/* The figures run their boxes to the viewBox edge, and a stroke is centred on the edge
   it draws, so half of every outer stroke fell outside the svg and was clipped: the
   outermost borders read thinner than the inner ones. The card's padding is the room
   they spill into. */
.hero-diagram .fig svg{overflow:visible}
.hf-lbl{font-family:var(--mono);font-size:9px;letter-spacing:.1em;text-transform:uppercase;fill:var(--ink-3)}
.hf-in{font-family:var(--mono);font-size:8.5px;letter-spacing:.08em;text-transform:uppercase;fill:var(--violet-ink);text-anchor:middle}
.hf-in.on{fill:var(--raise)}
.hf-in.mute{fill:var(--ink-3)}
.hf-num{font-family:var(--display);font-size:17px;font-weight:600;letter-spacing:-.03em;fill:var(--ink)}
.hf-big{font-family:var(--display);font-size:24px;font-weight:600;letter-spacing:-.035em;fill:var(--violet-ink)}
.hf-txt{font-family:var(--body);font-size:12.5px;fill:var(--ink)}
.hf-box{fill:var(--violet-tint);stroke:var(--violet);stroke-width:1.2}
.hf-box.on{fill:var(--violet);stroke:var(--violet)}
.hf-box.mute{fill:var(--paper-2);stroke:var(--line)}
.hf-box.gone{fill:none;stroke:var(--line);stroke-dasharray:4 3}
.hf-link{fill:none;stroke:var(--violet);stroke-width:1.4}
.hf-link.mute{stroke:var(--line);stroke-dasharray:3 3}
.hf-note{margin:12px 0 0;font-size:12.5px;color:var(--ink-3);line-height:1.5;text-align:center}
section{padding-block:clamp(52px,7vw,96px)}
.band{background:var(--paper-2);border-block:1px solid var(--line-2)}
.sec-head{display:flex;align-items:baseline;gap:14px 22px;margin-bottom:clamp(26px,3.4vw,40px);flex-wrap:wrap}
.sec-head .eyebrow{font-family:var(--mono);font-size:11px;letter-spacing:.06em;text-transform:uppercase;font-weight:500;color:var(--ink-4);flex:0 0 auto}
.sec-head .eyebrow::before{content:"";display:inline-block;width:22px;height:1px;background:var(--violet);vertical-align:middle;margin-right:11px;transform:translateY(-1px)}
.sec-head h2{font-size:clamp(24px,3vw,36px);letter-spacing:-.038em;flex:1 0 100%}
.sec-head .aside{margin-left:auto;font-size:13.5px;color:var(--ink-3);max-width:42ch;line-height:1.55}
@media(max-width:860px){
  .sec-head .aside{margin-left:0}
}
.prose{font-size:clamp(16px,1.45vw,17.5px);line-height:1.68;color:var(--ink-2);max-width:62ch}
.prose + .prose{margin-top:16px}
.prose b{color:var(--ink);font-weight:600}
blockquote.stmt{margin:0;font-family:var(--display);font-size:clamp(20px,2.6vw,29px);line-height:1.24;letter-spacing:-.032em;font-weight:500;color:var(--ink);max-width:26ch;border-left:2px solid var(--lime);padding-left:22px}
.two{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:clamp(28px,4vw,56px);align-items:start}
.two.wide-left{grid-template-columns:minmax(0,1.3fr) minmax(0,1fr)}
@media(max-width:860px){
  .two,.two.wide-left{grid-template-columns:1fr;gap:30px}
}
.fig{background:var(--raise);border:1px solid var(--line);border-radius:14px;padding:clamp(16px,2vw,22px);box-shadow:var(--shadow)}
.fig-cap{display:flex;justify-content:space-between;gap:10px;font-family:var(--mono);font-size:9.5px;letter-spacing:.1em;text-transform:uppercase;color:var(--ink-4);margin-bottom:16px}
.fig-cap b{color:var(--violet-ink);font-weight:500}
.fig svg{display:block;width:100%;height:auto;max-width:100%}
.people{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:clamp(18px,2.4vw,26px)}
@media(max-width:760px){
  .people{grid-template-columns:1fr}
}
.person{background:var(--raise);border:1px solid var(--line);border-radius:14px;padding:clamp(20px,2.4vw,28px)}
.person .who{display:flex;align-items:baseline;gap:10px;flex-wrap:wrap}
.person h3{font-size:21px;letter-spacing:-.028em}
.person .age{font-family:var(--mono);font-size:10.5px;letter-spacing:.07em;text-transform:uppercase;color:var(--ink-4)}
.person .role{margin-top:6px;font-family:var(--mono);font-size:10px;letter-spacing:.09em;text-transform:uppercase;color:var(--violet-ink);background:var(--violet-tint);display:inline-block;padding:4px 9px;border-radius:100px}
.person p{margin-top:14px;font-size:14.5px;line-height:1.62;color:var(--ink-3)}
.person .need{margin-top:16px;padding-top:14px;border-top:1px solid var(--line-2);font-size:13.5px;color:var(--ink-2)}
.person .need span{font-family:var(--mono);font-size:9.5px;letter-spacing:.1em;text-transform:uppercase;color:var(--ink-4);display:block;margin-bottom:5px}
.mods{display:grid;grid-template-columns:repeat(auto-fill,minmax(210px,1fr));gap:1px;background:var(--line);border:1px solid var(--line);border-radius:14px;overflow:hidden}
.mod{background:var(--raise);padding:18px 20px 20px}
/* auto-fill opens five 210px tracks across the shell, and the gap colour shows through
   any track a module does not fill. Four or six modules would leave blank tiles, so a
   list of four or six says so and gets a column count that always divides it: four as
   four, six as three by two, both two across on a tablet and one on a phone. */
.mods.four{grid-template-columns:repeat(4,minmax(0,1fr))}
.mods.six{grid-template-columns:repeat(3,minmax(0,1fr))}
@media(max-width:860px){.mods.four,.mods.six{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media(max-width:560px){.mods.four,.mods.six{grid-template-columns:1fr}}
.mod .n{font-family:var(--mono);font-size:9.5px;letter-spacing:.1em;color:var(--ink-4);font-weight:500}
.mod h4{margin-top:8px;font-size:16px;letter-spacing:-.02em}
.mod p{margin-top:6px;font-size:13px;line-height:1.5;color:var(--ink-3)}
.outs{display:grid;gap:0;border-top:1px solid var(--line)}
.out{display:grid;grid-template-columns:34px minmax(0,1fr);gap:16px;padding-block:18px;border-bottom:1px solid var(--line-2);align-items:baseline}
.out .k{font-family:var(--mono);font-size:10.5px;color:var(--ink-4);font-variant-numeric:tabular-nums}
.out p{font-size:15.5px;line-height:1.6;color:var(--ink-2)}
.out:last-child{border-bottom:0}
.reflect{background:var(--quote-bg);color:var(--quote-fg);border-block:1px solid var(--quote-border)}
.reflect blockquote{margin:0;font-family:var(--display);font-size:clamp(21px,3.2vw,38px);line-height:1.18;letter-spacing:-.035em;font-weight:500;max-width:30ch;color:var(--quote-fg)}
.reflect .hl{color:var(--lime)}
.qgrid{display:grid;grid-template-columns:minmax(0,1fr) 190px;gap:clamp(24px,4vw,56px);align-items:end}
@media(max-width:760px){
  .qgrid{grid-template-columns:1fr;gap:24px;align-items:start}
}
.qmark{font-family:var(--display);font-size:58px;line-height:.6;color:var(--lime);display:block;margin-bottom:14px}
/* Next project, above the closing band on every case study. Written by
   build/build_cases.py from one table, in work index order, looping. The next project
   is the card; the previous one is a quiet text link, because going on is the move
   worth making easy. The card is one link, and hovers the way the work index covers do.
   No lime: the closing band below spends it. */
section.next-sec{padding-block:clamp(44px,6vw,80px) clamp(40px,5vw,64px)}
.next-top{display:flex;align-items:baseline;justify-content:space-between;gap:16px;margin-bottom:16px}
.next-prev{font-family:var(--mono);font-size:10.5px;letter-spacing:.09em;text-transform:uppercase;font-weight:500;color:var(--ink-3);transition:color .18s}
.next-prev:hover{color:var(--violet-ink)}
.next-count{font-family:var(--mono);font-size:10.5px;letter-spacing:.09em;color:var(--ink-4);font-variant-numeric:tabular-nums}
.next-sr{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}
.next-card{
  display:grid;grid-template-columns:minmax(0,1.1fr) minmax(0,1fr);align-items:stretch;overflow:hidden;
  background:var(--raise);border:1px solid var(--line);border-radius:16px;box-shadow:var(--shadow);transition:border-color .25s
}
.next-card:hover{border-color:var(--violet)}
.next-copy{display:flex;flex-direction:column;justify-content:center;gap:12px;padding:clamp(24px,3.4vw,44px)}
.next-eyebrow{font-family:var(--mono);font-size:11px;letter-spacing:.06em;text-transform:uppercase;font-weight:500;color:var(--ink-4)}
.next-eyebrow::before{content:"";display:inline-block;width:22px;height:1px;background:var(--violet);vertical-align:middle;margin-right:11px;transform:translateY(-1px)}
.next-name{font-family:var(--display);font-size:clamp(30px,4.4vw,52px);font-weight:600;letter-spacing:-.045em;line-height:1;color:var(--ink)}
.next-sum{font-size:14.5px;line-height:1.6;color:var(--ink-3);max-width:44ch}
.next-go{margin-top:6px;font-family:var(--mono);font-size:10.5px;letter-spacing:.09em;text-transform:uppercase;font-weight:500;color:var(--violet-ink)}
.next-go .arw{display:inline-block;margin-left:6px;transition:transform .2s ease}
.next-card:hover .next-go .arw{transform:translateX(4px)}
.next-cover{position:relative;overflow:hidden;min-height:220px;border-left:1px solid var(--line)}
.next-cover img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;filter:var(--photo-filter);transition:transform .6s cubic-bezier(.22,1,.36,1)}
.next-card:hover .next-cover img{transform:scale(1.035)}
@media(max-width:760px){
  .next-card{grid-template-columns:minmax(0,1fr)}
  .next-cover{order:-1;aspect-ratio:16/9;min-height:0;border-left:0;border-bottom:1px solid var(--line)}
}
.cta-sec{border-top:1px solid var(--line)}
.cta-sec h2{font-size:clamp(30px,5.4vw,58px);letter-spacing:-.045em;max-width:18ch}
.cta-sec h2 .em{color:var(--violet)}
.btnrow{margin-top:28px;display:flex;flex-wrap:wrap;gap:10px;align-items:center}
.btn{display:inline-flex;align-items:center;gap:9px;padding:12px 20px;border-radius:100px;font-size:14px;font-weight:600;border:1px solid transparent;transition:transform .16s,background .2s,border-color .2s,color .2s}
.btn:active{transform:translateY(1px)}
.btn-1{background:var(--btn);color:var(--on-btn);box-shadow:var(--shadow)}
.btn-1:hover{background:var(--violet);color:var(--on-violet)}
.btn-2{border-color:var(--line);color:var(--ink);background:var(--raise)}
.btn-2:hover{border-color:var(--violet);color:var(--violet-ink)}
.mail{font-family:var(--mono);font-size:clamp(13px,1.5vw,15px);color:var(--ink);border-bottom:2px solid var(--lime);padding-bottom:2px}
.mail:hover{color:var(--violet)}
footer{border-top:1px solid var(--line);padding-block:24px 32px}
.foot{display:flex;flex-wrap:wrap;gap:12px 24px;align-items:center;font-family:var(--mono);font-size:10.5px;letter-spacing:.08em;text-transform:uppercase;color:var(--ink-4)}
.foot a{color:var(--ink-3)}
.foot a:hover{color:var(--violet)}
.foot .sp{margin-left:auto}
@media(max-width:640px){
  .foot .sp{margin-left:0}
}
.dg-l{font-family:var(--mono);font-size:11.5px;letter-spacing:.07em;text-transform:uppercase;fill:var(--ink-4)}
.dg-k{font-family:var(--mono);font-size:14px;letter-spacing:.05em;text-transform:uppercase;fill:var(--ink);font-weight:500}
.dg-b{font-family:"Instrument Sans",Arial,sans-serif;font-size:14.5px;fill:var(--ink-3)}
.dg-a{font-family:var(--mono);font-size:12px;letter-spacing:.06em;text-transform:uppercase;fill:var(--violet-ink);font-weight:500}
@media (prefers-reduced-motion: no-preference){
  .rise{animation:rise .65s cubic-bezier(.2,.7,.2,1) both}
  .rise-1{animation-delay:.04s}
  .rise-2{animation-delay:.1s}
  .rise-3{animation-delay:.16s}
  .rise-4{animation-delay:.22s}
  @keyframes rise{from{opacity:.6;transform:translateY(8px)}to{opacity:1;transform:none}}
}
.stmt-row{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:clamp(28px,4vw,56px);align-items:start}
@media(max-width:860px){
  .stmt-row{grid-template-columns:1fr;gap:28px}
}
.rail-list{display:grid;gap:0;border-top:1px solid var(--line)}
.rail-list div{display:grid;grid-template-columns:34px minmax(0,1fr);gap:16px;padding-block:16px;border-bottom:1px solid var(--line-2);align-items:baseline}
.rail-list div:last-child{border-bottom:0}
.rail-list .k{font-family:var(--mono);font-size:10.5px;color:var(--ink-4);font-variant-numeric:tabular-nums}
.rail-list p{font-size:15px;line-height:1.6;color:var(--ink-2)}
.rail-list p b{color:var(--ink);font-weight:600}
.numbers{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:20px;border-top:1px solid var(--line);padding-top:20px}
@media(max-width:760px){
  .numbers{grid-template-columns:repeat(2,minmax(0,1fr));gap:24px 20px}
}
.numbers dt{font-family:var(--mono);font-size:10px;letter-spacing:.1em;text-transform:uppercase;color:var(--ink-4);font-weight:500}
.numbers dd{margin:7px 0 0;font-family:var(--display);font-size:clamp(24px,2.9vw,31px);font-weight:600;letter-spacing:-.035em;line-height:1;font-variant-numeric:tabular-nums}
.numbers small{display:block;margin-top:6px;font-size:12.5px;color:var(--ink-3);line-height:1.45;font-weight:400;letter-spacing:0;font-family:var(--body)}
.chips{display:flex;flex-wrap:wrap;gap:7px;margin-top:18px}
.chips span{
  font-family:var(--mono);font-size:10.5px;letter-spacing:.05em;text-transform:uppercase;color:var(--ink-3);
  border:1px solid var(--line);background:var(--raise);padding:5px 10px;border-radius:100px
}
.fig-note{margin-top:14px;font-size:12.5px;color:var(--ink-3);line-height:1.5}

/* ============================================================
   Product showcase

   An always dark band carrying a slideshow: a frame with a fixed
   aspect ratio, a scroll snap track inside it, and a control bar
   under it. Tino and DataGuard both use it, which is why it lives
   here rather than in a page.

   The band spends its one lime on the <b> in .sc-sub, so every
   control below is --quote-fg or a color-mix of it.
   ============================================================ */

.showcase{background:var(--quote-bg);color:var(--quote-fg);border-block:1px solid var(--quote-border);position:relative;overflow:hidden;padding-block:clamp(44px,6vw,80px)}
.showcase::before{
  content:"";position:absolute;left:clamp(20px,5vw,64px);top:clamp(40px,6vw,72px);width:340px;height:340px;pointer-events:none;
  background-image:radial-gradient(currentColor 2px, transparent 2px);background-size:52px 52px;opacity:.16;
  mask-image:radial-gradient(circle at 0 0, rgba(0,0,0,.9), transparent 72%);
  -webkit-mask-image:radial-gradient(circle at 0 0, rgba(0,0,0,.9), transparent 72%)
}
/* The shot used to run 900px wide and bleed off the right edge, with the copy
   floating vertically centred against it. Both columns are flush now: the stage
   takes the width the copy leaves it and aspect-ratio turns that into its height,
   so the picture is exactly as tall as the text beside it and no arithmetic has to
   be kept in sync by hand.

   The second column is minmax(0,1fr) rather than auto because the stage is not the
   column's content: the track inside it is out of flow, so an auto track would size
   itself to the control bar and collapse the picture to about 250px. */
.sc-wrap{position:relative;max-width:var(--maxw);margin:0 auto;padding-inline:var(--pad);display:grid;grid-template-columns:minmax(220px,296px) minmax(0,1fr);gap:clamp(20px,3vw,40px);align-items:stretch;justify-content:start}
@media(max-width:900px){
  .sc-wrap{grid-template-columns:1fr;gap:28px;justify-content:stretch}
}
.sc-copy{display:flex;gap:18px;align-items:flex-start}
.sc-by{writing-mode:vertical-rl;transform:rotate(180deg);font-family:var(--mono);font-size:10px;letter-spacing:.14em;text-transform:uppercase;color:var(--quote-mute);white-space:nowrap;padding-block:2px}
@media(max-width:900px){
  .sc-by{display:none}
}
.sc-copy h2{font-family:var(--display);font-size:clamp(28px,3.6vw,46px);line-height:1.06;letter-spacing:-.04em;font-weight:600;color:var(--quote-fg)}
.sc-copy .sc-sub{margin-top:14px;font-size:14px;line-height:1.6;color:var(--quote-mute);max-width:30ch}
.sc-copy .sc-sub b{color:var(--lime);font-weight:500}
/* The shots are UI boards on an always dark band, so they skip --photo-filter, which
   exists to dim photographs in dark mode and would do the opposite of what is wanted
   here. They carry no grade either: they are finished artwork on their own colours.

   No coloured shadow: the frame is a single neutral hairline mixed from --quote-fg,
   so nothing tints the band around the shot. The liveliness comes from the grain over
   the image, not from a glow. */
.sc-media{position:relative;display:flex;flex-direction:column;gap:14px;min-width:0}
.sc-stage{
  position:relative;isolation:isolate;overflow:hidden;border-radius:14px;aspect-ratio:16/9;
  box-shadow:0 0 0 1px color-mix(in srgb,var(--quote-fg) 16%,transparent)
}
/* Grain, the same layer the homepage portrait carries: same tile, same
   --photo-grain, same overlay blend, and on ::after exactly as it is there.
   isolation on .sc-stage keeps the blend inside the frame rather than letting
   it reach the band behind. It stays on the frame rather than moving to the track,
   because a layer inset into a scroll container scrolls away with the content. */
.sc-stage::after{
  content:"";position:absolute;inset:0;pointer-events:none;z-index:2;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='g' color-interpolation-filters='sRGB'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.8' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3CfeComponentTransfer%3E%3CfeFuncR type='linear' slope='2' intercept='-.5'/%3E%3CfeFuncG type='linear' slope='2' intercept='-.5'/%3E%3CfeFuncB type='linear' slope='2' intercept='-.5'/%3E%3CfeFuncA type='table' tableValues='1 1'/%3E%3C/feComponentTransfer%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23g)'/%3E%3C/svg%3E");
  background-size:160px 160px;opacity:var(--photo-grain);mix-blend-mode:overlay
}
/* Scroll snapping rather than a transform track: a swipe on a phone and a trackpad
   gesture on a laptop then work on their own, and the buttons are one scrollTo. The
   scrollbar is hidden because the dots already say where the reader is. */
.sc-track{
  position:absolute;inset:0;display:flex;overflow-x:auto;overflow-y:hidden;
  scroll-snap-type:x mandatory;scroll-behavior:smooth;scrollbar-width:none
}
.sc-track::-webkit-scrollbar{display:none}
@media (prefers-reduced-motion: reduce){
  .sc-track{scroll-behavior:auto}
}
.sc-slide{
  position:relative;flex:0 0 100%;min-width:0;height:100%;overflow:hidden;
  scroll-snap-align:center;scroll-snap-stop:always
}
.sc-shot{display:block;width:100%;height:100%;object-fit:cover;object-position:left top}
/* A video slide keeps the browser's own controls rather than a player rebuilt here:
   they are keyboard reachable, they scrub, and a second set of buttons painted over
   them would only be a worse copy. showcase.js puts them there on hover and on
   keyboard focus and takes them away again, so at rest the slide is a picture.

   The sound button is the exception that stays. The video runs muted, and a reader
   who cannot see that has no reason to go looking for the switch. It sits in the
   corner the controls do not use, and loses its label once the sound is on. */
.sc-slide.video .sc-shot{object-fit:contain;background:var(--quote-bg)}
/* An embedded player, for a video that lives on Vimeo rather than as a file. It lies
   over a local poster, so the slide draws before the player does, or if it never does. */
.sc-slide.embed iframe.sc-shot{position:absolute;inset:0;border:0}
.sc-sound{
  position:absolute;left:12px;top:12px;z-index:1;display:inline-flex;align-items:center;gap:6px;
  font-family:var(--mono);font-size:10px;letter-spacing:.09em;text-transform:uppercase;
  color:var(--quote-fg);background:color-mix(in srgb,var(--quote-bg) 72%,transparent);
  border:1px solid color-mix(in srgb,var(--quote-fg) 36%,transparent);border-radius:100px;
  padding:5px 10px;cursor:pointer;transition:border-color .18s,background .18s
}
.sc-sound:hover{border-color:var(--quote-fg);background:var(--quote-bg)}
.sc-sound svg{width:11px;height:11px;display:block;fill:currentColor}
.sc-sound svg .ln{fill:none;stroke:currentColor;stroke-width:2.2;stroke-linecap:round}
.sc-sound .icon-sound{display:none}
.sc-slide.sound-on .sc-sound .icon-sound{display:block}
.sc-slide.sound-on .sc-sound .icon-muted{display:none}
.sc-slide.sound-on .sc-sound span{display:none}
.sc-slide.sound-on .sc-sound{padding:6px}
.sc-bar{display:flex;align-items:center;gap:12px}
.sc-dots{display:flex;align-items:center;gap:6px;flex:0 0 auto}
.sc-dot{
  width:7px;height:7px;padding:0;border:0;border-radius:100px;cursor:pointer;
  background:color-mix(in srgb,var(--quote-fg) 42%,transparent);transition:width .22s,background .22s
}
.sc-dot[aria-current="true"]{width:22px;background:var(--quote-fg)}
.sc-cap{
  font-family:var(--mono);font-size:10.5px;letter-spacing:.09em;text-transform:uppercase;
  color:var(--quote-mute);white-space:nowrap;overflow:hidden;text-overflow:ellipsis
}
.sc-btns{margin-left:auto;display:flex;gap:8px;flex:0 0 auto}
.sc-btn{
  width:32px;height:32px;display:inline-flex;align-items:center;justify-content:center;padding:0;
  border:1px solid color-mix(in srgb,var(--quote-fg) 36%,transparent);border-radius:100px;
  background:transparent;color:var(--quote-fg);cursor:pointer;transition:border-color .18s,background .18s
}
.sc-btn:hover{border-color:var(--quote-fg);background:color-mix(in srgb,var(--quote-fg) 10%,transparent)}
.sc-btn svg{width:13px;height:13px;display:block;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.sc-btn .icon-play{fill:currentColor}
.sc-btn .icon-pause{display:none}
.sc-media.playing .sc-btn .icon-pause{display:block}
.sc-media.playing .sc-btn .icon-play{display:none}
/* Announced, not shown: the caption carries the same words for anyone reading it. */
.sc-live{position:absolute;width:1px;height:1px;margin:-1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}

