/* ============================================================
   case-study.css — components shared by every /work/* page
   The 22 classes common to all case studies. Values transcribed
   from the published Webflow stylesheet.

   Load order: shared.css → case-study.css → (page-specific).
   ============================================================ */

/* ── Hero ─────────────────────────────────────────────────── */

.section-hero {
  padding-top: 100px;
  padding-bottom: 100px;
  color: var(--text--primary);
  background-color: #0000;
}
/* Used by Woori Bank and Nexus. */
.section-hero.wb {
  margin-bottom: 60px;
  margin-left: 0;
  padding-bottom: 0;
  background-color: #0000;
}

/* Wide browser frame — the alternative to the phone mockup.
   Promoted from work-idc.css once Nexus needed it too. */
.div_hero_wrapper--web {
  width: 100%;
  max-width: 100%;
  height: 700px;
  margin-bottom: 20px;
  background-color: #838297;
}
.div_hero_wrapper--web.nexus {
  height: auto;
  background-color: #0000;
}
/* The frame is as tall as the screenshot, with no black band above and
   below it (the fixed 700px frame letterboxed it by ~74px each side). */
.div_hero_wrapper--web.irise { height: auto; background-color: #000; }

.section-hero.roche { padding-top: 0; }

.div-block-102 {
  display: flex;
  align-items: center;
  width: auto;
  height: 100%;
  margin-left: auto;
  margin-right: auto;
}

.html_uid_ui {
  z-index: auto;
  display: flex;
  position: relative;
  inset: 0%;
  width: auto;
  height: auto;
  border-radius: 0;
  object-fit: fill;
  overflow: clip;
}
.html_uid_ui.radius {
  border-radius: 8px;
  color: #1a1b1f;
  overflow: hidden;
}

.grid_hero {
  display: grid;
  grid-template-rows: auto auto;
  grid-template-columns: 1fr 1fr 1fr;
  grid-column-gap: 16px;
  grid-row-gap: 16px;
  grid-auto-columns: 1fr;
  grid-auto-flow: row;
  flex-flow: wrap;
  justify-content: space-between;
  max-width: 980px;
  color: var(--text--primary);
}

/* Webflow places these with generated #w-node-* ids; same result by class.
   Both hero lines span all three columns. */
.grid_hero > .heading_hero-subtitle-1 { grid-area: 1 / 1 / 2 / 4; }
.grid_hero > .heading_hero-title      { grid-area: 2 / 1 / 3 / 4; }

.heading_hero-subtitle-1 {
  margin-top: auto;
  margin-bottom: auto;
  color: var(--gray-400);
  font-family: Geist, sans-serif;
  font-size: 24px;
  font-weight: 500;
  line-height: 160%;
}

.heading_hero-title {
  display: flex;
  justify-content: flex-start;
  width: 100%;
  margin-top: 0;
  margin-bottom: 0;
  padding-left: 0;
  color: #000;
  font-family: Geist, sans-serif;
  font-size: 60px;
  font-weight: 600;
  letter-spacing: normal;
  line-height: 1.15;   /* larger type, tighter ratio: was 160% */
}

.paragraph_proj-brief {
  width: 100%;
  /* Was a flat 980px — the image wrapper's width, not a reading width.
     Its parent is the full window, so that 980 with auto margins was what
     put it in line with the hero title. Narrowing it to the measure alone
     re-centred it and left the text starting 218px to the right of the
     title, so the left margin now reproduces the column's offset and the
     right one takes up the slack. */
  max-width: var(--measure);
  margin: 0 auto 0 max(0px, calc((100% - 980px) / 2));
  padding-left: 0;
  color: var(--gray-600);
  font-family: Geist, sans-serif;
  font-size: 16px;
  font-weight: 400;
  line-height: 170%;
}
.paragraph_proj-brief.spacing {
  margin-top: 5vh;
  margin-bottom: 5vh;
  text-align: center;
}

/* ── Hero device mockup ───────────────────────────────────── */

.div_hero_wrapper--ui {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  position: relative;
  width: 100%;
  max-width: 980px;
  margin: 60px auto 0;
  background-color: #0000;
  overflow: visible;
}

.div_hero_wrapper--phone {
  position: relative;
  width: 100%;
  max-width: 980px;
  height: 700px;
  margin-bottom: 20px;
  margin-left: auto;
  margin-right: auto;
  padding-left: 0;
  padding-right: 0;
  border-radius: 0;
  background-color: #d7ebff;
  background-image: linear-gradient(#b8b8b880, #b8b8b880);
}
.div_hero_wrapper--phone.lg { background-color: #ffd7d8; }

.div_hero_phone {
  position: relative;
  top: 50px;
  width: 100%;
  height: 100%;
  max-height: 600px;
  background-position: 50%;
  background-repeat: no-repeat;
  background-size: contain;
}
.div_hero_phone.wb { background-image: url(../assets/phone-frame-white.svg); }
.div_hero_phone.lg { background-image: url(../assets/phone-frame-black.svg); }

.div_hero_wrapper--html {
  z-index: 0;
  display: block;
  position: relative;
  inset: 0;
  align-items: center;
  width: 253px;
  height: 450px;
  margin: auto;
  background-color: #0000;
  object-fit: cover;
  object-position: 50% 50%;
  overflow: visible;
}
.div_hero_wrapper--html.lg {
  position: absolute;
  top: -30px;
  width: 233px;
  height: 504px;
  border-radius: 20px;
  background-color: var(--black);
  overflow: hidden;
}
.div_hero_wrapper--html.wb { top: -491px; }
.div_hero_wrapper--html.idc {
  top: 100px;
  width: 698px;
  max-width: none;
  height: 496px;
  max-height: 496px;
  border-radius: 12px;
  overflow: hidden;
}
/* Narrower than the 698px clip (480–767px): scale it down instead of spilling. */
@media (min-width: 480px) {
  .div_hero_wrapper--html.idc { top: 0; width: min(698px, 100% - 32px); height: auto; aspect-ratio: 698 / 496; }
  .div_hero_wrapper--web:has(> .div_hero_wrapper--html.idc) { display: flex; align-items: center; }
}

/* Sits behind the mockup media while it loads. */
.txt_loading {
  z-index: -1;
  display: flex;
  position: absolute;
  inset: 0%;
  justify-content: center;
  align-items: center;
  color: var(--white);
  font-family: Geist, sans-serif;
  text-align: center;
}

/* ── Project role / meta grid ─────────────────────────────── */

.grid_proj-role {
  display: grid;
  grid-template-rows: auto auto;
  grid-template-columns: 1fr 1fr;
  grid-column-gap: 56px;
  grid-row-gap: 36px;
  width: 980px;
  max-width: 980px;
  margin-left: auto;
  margin-right: auto;
}

/* Items size to content rather than stretching to the row, matching the
   per-item place-self the published site sets via #w-node-* rules. */
.grid_proj-role > * { place-self: start; }

.div_hero_subtitle {
  display: flex;
  flex-flow: column;
  flex: 0 auto;
  order: 0;
  justify-content: flex-start;
  align-self: stretch;
  align-items: flex-start;
}

.heading_hero-subtitle-2 {
  display: flex;
  width: auto;
  margin-top: 0;
  margin-bottom: 0;
  color: #000;
  font-family: Geist, sans-serif;
  font-size: 16px;
  font-weight: 700;
  line-height: 170%;
}

.heading_hero-p {
  display: block;
  margin-top: 0;
  margin-bottom: auto;
  color: #000;
  font-family: Geist, sans-serif;
  font-size: 16px;
  line-height: 170%;
}
.heading_hero-p.margin-btm { margin-bottom: 10px; }

/* ── How might we ─────────────────────────────────────────── */

.heading_how-might-we {
  max-width: 780px;
  margin-top: 0;
  margin-bottom: 120px;
  color: var(--black);
  font-family: Geist, sans-serif;
  font-size: 48px;
  font-weight: 600;
  line-height: 160%;
  text-align: left;
}

/* ── The workhorse content block ──────────────────────────── */

.grid_txt {
  display: grid;
  grid-template: "." "." / minmax(auto, 480px) minmax(auto, 380px);
  grid-column-gap: 120px;
  grid-row-gap: 8px;
  grid-auto-columns: 1fr;
  max-width: 980px;
  margin-bottom: 60px;
  margin-left: auto;
  margin-right: auto;
  padding-left: 0;
  padding-right: 0;
}
.grid_txt.no-subtitle {
  grid-template-rows: auto;
  grid-row-gap: 8px;
  margin-bottom: 60px;
}
.grid_txt.subtitleonly {
  grid-template-rows: auto;
  grid-template-columns: minmax(auto, 480px);
  margin-bottom: 20px;
}
.grid_txt._1-col {
  display: grid;
  grid-template-rows: auto auto auto;
  grid-template-columns: minmax(auto, auto);
  grid-column-gap: 120px;
  grid-row-gap: 16px;
  grid-auto-columns: 1fr;
  grid-auto-flow: row;
  margin-top: 5vh;
}
/* ── Text blocks: label and headline left, description right ──
   On a wide screen each block is two columns on the 980px grid: the
   eyebrow and the headline on the left, every paragraph and list on the
   right. The split is the highlights component's own — 5fr / 7fr with a
   56px gap — so headlines stand over the highlights list and paragraphs
   over its video, and the right column (539px) still holds the ~70
   character measure.

   The blocks vary — most are eyebrow + headline + paragraphs, some have no
   eyebrow, two are paragraphs only, one is an eyebrow alone — so the
   placement is done without wrapping anything:

   · the eyebrow takes the first row on the left, the headline the rows
     below it;
   · an empty ::before claims the first row on the right, so the first
     paragraph starts level with the HEADLINE rather than the eyebrow, and
     a paragraphs-only block starts level with the paragraphs above it;
   · the headline spans down to a final 1fr row, so when it is taller than
     its paragraphs the extra height lands there instead of being shared
     out between the paragraphs as gaps.

   Below 992px it is one centred column at the paragraph measure. */

@media screen and (min-width: 992px) {
  .grid_txt._1-col {
    max-width: 980px;
    grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
    grid-template-rows: repeat(12, auto) 1fr;
    column-gap: 56px;
    row-gap: 0;
  }
  .grid_txt._1-col::before {
    content: "";
    grid-column: 2;
    grid-row: 1;
  }
  .grid_txt._1-col > .heading_grid-txt_subtitle {
    grid-column: 1;
    grid-row: 1;
    padding-bottom: 12px;
  }
  .grid_txt._1-col > .heading_grid-txt_summary {
    grid-column: 1;
    grid-row: 2 / -1;
  }
  .grid_txt._1-col > :is(p, ul) {
    grid-column: 2;
    margin-top: 0;
  }
  .grid_txt._1-col > :is(p, ul) + :is(p, ul) { margin-top: 16px; }
}

@media screen and (max-width: 991px) {
  /* One reading column at the paragraph measure, centred. */
  .grid_txt._1-col { max-width: var(--measure); }

  /* Everything flows in source order. The phone rules carried over from
     Webflow pin every `.grid_txt > .paragraph_body` to one cell
     (grid-area 3 / 1 / 4 / 2), so below 480px a block's second and third
     paragraphs were drawn on top of its first. The reset meant to undo that
     is declared earlier with equal specificity and lost; this one is more
     specific, so it holds at every narrow width. */
  .grid_txt._1-col > :is(.heading_grid-txt_subtitle, .heading_grid-txt_summary, .paragraph_body, ul) {
    grid-area: auto;
  }
  /* The list's own 20px top margin would stack on the 16px row gap. */
  .grid_txt._1-col > ul { margin-top: 0; }
}

/* ── Story-page rhythm ───────────────────────────────────────
   Nexus, IRISe and Data Abstraction share one structure — sections of a
   centred text block followed by 980px media — so they share one spacing
   scale, opted into by `case-story` on <body>.

   The space between sections used to be an accident of stacking: each
   section's own 60px top and 140px bottom, plus a 60px margin under every
   text block, a 45px (5vh) margin under every image, a 140px margin under
   two media groups and a 100px pad under one wrapper. Which of those
   happened to be last decided the gap, so the gaps between sections ran
   from 140px to 385px on the same page. Every one of those spacers is
   cleared here and replaced by four deliberate steps:

     section   → section      --story-section   the largest break
     media     → next text    --story-sub       a new topic, same section
     text      → its media    --story-block     a block and what it shows
     media     → media        --story-stack     one group of images

   Horizontal margins are left alone: the text column is centred with
   auto side margins, and only top and bottom are reset. */

.case-story {
  --story-section: 160px;
  --story-sub: 96px;
  --story-block: 48px;
  --story-stack: 24px;
}

/* Each section carries half the break above and half below, so two
   sections meet at exactly one break. */
.case-story .section {
  padding-top: calc(var(--story-section) / 2);
  padding-bottom: calc(var(--story-section) / 2);
}
.case-story .section > .wrapper {
  padding-top: 0;
  padding-bottom: 0;
}

/* Clear the stacked spacers… */
.case-story .section > .wrapper > * {
  margin-top: 0;
  margin-bottom: 0;
}
.case-story .section > .wrapper > .wrapper_980w > *,
.case-story .section > .wrapper > .tabs > * {
  margin-bottom: 0;
}

/* …and set the flow. */
.case-story .section > .wrapper > * + * { margin-top: var(--story-block); }
.case-story .section > .wrapper > .wrapper_980w + .wrapper_980w { margin-top: var(--story-stack); }
.case-story .section > .wrapper > .wrapper_980w + .grid_txt { margin-top: var(--story-sub); }
/* A media group with nothing in it yet — a slot still waiting for its
   video — takes no height but would still collect its flow margin, adding
   a phantom 48px (and 24px for a second one) to the break. It stays out
   of the flow until something is put in it. */
.case-story .section > .wrapper > .wrapper_980w:not(:has(img, video, iframe, picture, .highlights, .tabs-menu)) {
  display: none;
}
/* The closing "next project" link belongs to the line above it. */
.case-story .section > .wrapper > .txt_link { margin-top: 20px; }

@media screen and (max-width: 991px) {
  .case-story {
    --story-section: 128px;
    --story-sub: 88px;
    --story-block: 40px;
    --story-stack: 20px;
  }
}
@media screen and (max-width: 767px) {
  .case-story {
    --story-section: 96px;
    --story-sub: 72px;
    --story-block: 32px;
    --story-stack: 16px;
  }
}
@media screen and (max-width: 479px) {
  .case-story {
    --story-section: 80px;
    --story-sub: 64px;
  }
}

.grid_txt._1-col._1-row { grid-template-rows: auto; }
.grid_txt._1-col._4-row { grid-template-rows: auto auto auto auto; }

/* Subtitle sits above the summary in the 480px column; the body paragraph
   occupies the 380px column, aligned with the summary. */
.grid_txt > .heading_grid-txt_subtitle { grid-area: 1 / 1 / 2 / 2; }
.grid_txt > .heading_grid-txt_summary  { grid-area: 2 / 1 / 3 / 2; }
.grid_txt > .paragraph_body            { grid-area: 2 / 2 / 3 / 3; }

/* Without a subtitle the block collapses to a single row. */
.grid_txt.no-subtitle > .heading_grid-txt_summary { grid-area: 1 / 1 / 2 / 2; }
.grid_txt.no-subtitle > .paragraph_body           { grid-area: 1 / 2 / 2 / 3; }

/* ._1-col is a single column — hand it back to auto-placement, or the
   two-column areas above would spill into a phantom second column. */
.grid_txt._1-col > * { grid-area: auto; }

.heading_grid-txt_subtitle {
  width: 100%;
  max-width: 980px;
  margin: 0 auto;
  color: #757575;
  font-family: Geist, sans-serif;
  font-size: 16px;
  font-weight: 400;
  line-height: 170%;
}

.heading_grid-txt_summary {
  width: 100%;
  margin-top: 0;
  margin-bottom: 0;
  color: #000;
  font-family: Geist, sans-serif;
  font-size: 32px;
  font-weight: 500;
  line-height: 1.25;   /* display type: was 170%, a body-text ratio */
  white-space: normal;
  word-break: normal;
}
.heading_grid-txt_summary.center { max-width: 100%; text-align: center; }
.heading_grid-txt_summary.h2 { font-size: 26px; line-height: 130%; }

.paragraph_body {
  flex: 0 auto;
  width: 100%;
  /* Was 100%, which is the width of a wrapper sized for images. */
  max-width: var(--measure);
  margin-bottom: 0;
  color: var(--text--secondary);
  font-family: Geist, sans-serif;
  font-weight: 400;
  line-height: 170%;
  text-decoration: none;
}
/* Centred, but still to the measure — it loads after shared.css, so an
   unqualified 100% here would quietly undo the cap. */
.paragraph_body.center {
  max-width: var(--measure);
  margin-top: 0;
  margin-left: auto;
  margin-right: auto;
  text-align: center;
}

/* Secondary note — sits under a project-role item or a body paragraph. */
.paragraph_body-2 {
  color: var(--text--secondary);
  line-height: 160%;
}
.paragraph_body-2.dark {
  color: var(--text--tertiary);
  font-weight: 400;
  line-height: 160%;
}

/* Inline emphasis inside body copy. (Class name's typo is Webflow's.) */
.body-highilight { color: var(--black); }
.body-highilight.dark {
  color: var(--text--primary);
  font-style: normal;
  font-weight: 400;
}

/* ── Principles list ──────────────────────────────────────────
   An unbulleted list of named principles, used where a case study
   enumerates the rules it designed against.
   ──────────────────────────────────────────────────────────── */

.list-5 {
  max-width: 980px;
  margin-left: auto;
  margin-right: auto;
  padding-left: 0;
  color: var(--text--secondary);
  list-style-type: none;
}

.list-item {
  margin-bottom: 20px;
  color: var(--text--secondary);
  font-family: Geist, sans-serif;
  font-size: 16px;
  line-height: 170%;
}

@media screen and (max-width: 479px) {
  .list-item { line-height: 170%; }
}

/* ── Figures and captions ─────────────────────────────────── */

.img { width: 100%; }

.txt_caption {
  flex: 0 auto;
  margin-top: 20px;
  color: var(--gray-700);
  font-family: Geist, sans-serif;
  font-size: 20px;
  line-height: 170%;
  text-align: center;
}
.txt_caption.center { margin-left: auto; margin-right: auto; }

.txt_link {
  flex: 0 auto;
  width: 100%;
  max-width: 380px;
  margin-bottom: 0;
  color: var(--black);
  font-family: Geist, sans-serif;
  font-weight: 400;
  line-height: 32px;
  text-decoration: none;
}
.txt_link.center {
  max-width: 100%;
  margin-top: 20px;
  font-family: Geist, sans-serif;
  font-size: 24px;
  line-height: 170%;
  text-align: center;
}

.text-block-35 {
  font-family: Geist, sans-serif;
  line-height: 170%;
  text-align: center;
}

/* ── Dark variants (used by the Roche / Nexus case studies) ── */

.heading_hero-title.dark { color: var(--text--primary); }
.heading_hero-subtitle-1.dark { color: var(--text--secondary); }
.heading_hero-subtitle-2.dark { width: auto; color: var(--text--primary); font-size: 17px; }
.heading_hero-p.dark { color: var(--text--secondary); }
.heading_grid-txt_summary.dark { color: var(--text--primary); }
.heading_grid-txt_subtitle.dark { font-weight: 700; line-height: 160%; }
.paragraph_body.dark { color: var(--text--secondary); }
.paragraph_proj-brief.dark { display: block; color: var(--text--secondary); overflow: visible; }
.paragraph_proj-brief.dark.hide { display: none; }
.text-block-35.dark { color: var(--text--secondary); }
.txt_link.center.dark { color: var(--text--primary); }

/* ── ≤ 991px ──────────────────────────────────────────────── */

@media screen and (max-width: 991px) {
  .section-hero.wb { padding-left: 2rem; padding-right: 2rem; }
  .paragraph_proj-brief { width: 100%; }
  .heading_how-might-we { margin-bottom: 0; }
  .div_hero_wrapper--html { width: 200px; height: 400px; }
  .div_hero_wrapper--phone { flex: 0 auto; }
  .grid_proj-role,
  .img { width: 100%; }
}

/* ── ≤ 767px ──────────────────────────────────────────────── */

@media screen and (max-width: 767px) {
  .heading_hero-subtitle-1.dark { font-size: 20px; }
}

/* ── ≤ 479px ──────────────────────────────────────────────── */

@media screen and (max-width: 479px) {
  .section-hero { padding-left: 1.5rem; padding-right: 1.5rem; }
  .section-hero.wb { max-width: 100%; padding-left: 1.5rem; padding-right: 1.5rem; }
  .div_hero_wrapper--web { height: 280px; margin-bottom: 20px; }
  .div_hero_wrapper--web.nexus,
  .div_hero_wrapper--web.irise { height: auto; }
  .div-block-102 { width: auto; margin-left: 0%; margin-right: 0%; }
  .html_uid_ui { border-radius: 0; }

  .grid_hero {
    grid-template-rows: auto auto;
    grid-template-columns: 100%;
    max-width: 100%;
    padding-left: 0;
    padding-right: 0;
  }

  .heading_hero-title { width: 100%; max-width: 100%; font-size: 34px; line-height: 1.2; }
  .heading_hero-title.dark { font-size: 32px; line-height: 1.2; }
  .heading_hero-subtitle-1.dark { font-size: 18px; }

  .paragraph_proj-brief { max-width: 100%; font-size: 16px; line-height: 32px; }
  .paragraph_proj-brief.dark { line-height: 170%; }

  .div_hero_wrapper--phone {
    height: 500px;
    background-image: linear-gradient(#b8b8b880, #b8b8b880);
  }
  .div_hero_wrapper--html {
    position: absolute;
    top: -24px;
    width: 100%;
    height: 375px;
  }
  .div_hero_wrapper--html.lg {
    top: 0;
    bottom: 5.5%;
    width: 194px;
    height: 420px;
    border-radius: 19px;
  }
  .div_hero_wrapper--html.wb { top: -25px; }
  .div_hero_wrapper--html.idc {
    position: relative;
    top: 52px;
    width: 240px;
    height: 173px;
    border-radius: 6px;
    overflow: hidden;
  }
  .div_hero_phone {
    top: 0;
    width: 100%;
    height: 100%;
    max-height: 100%;
    padding-bottom: 0;
    padding-right: 0;
  }

  .grid_proj-role { grid-template-rows: auto auto auto auto; grid-template-columns: 1fr; }

  .heading_how-might-we {
    max-width: 100%;
    padding-bottom: 120px;
    font-size: 32px;
    line-height: 48px;
  }

  .grid_txt {
    grid-template-rows: auto auto auto;
    grid-template-columns: 100%;
    max-width: 100%;
  }
  .grid_txt.no-subtitle { grid-template-rows: auto; }

  /* Single column — restack instead of keeping the two-column placement. */
  .grid_txt > .heading_grid-txt_subtitle { grid-area: 1 / 1 / 2 / 2; }
  .grid_txt > .heading_grid-txt_summary  { grid-area: 2 / 1 / 3 / 2; }
  .grid_txt > .paragraph_body            { grid-area: 3 / 1 / 4 / 2; }
  .grid_txt.no-subtitle > .heading_grid-txt_summary { grid-area: 1 / 1 / 2 / 2; }
  .grid_txt.no-subtitle > .paragraph_body           { grid-area: 2 / 1 / 3 / 2; }

  .grid_hero > .heading_hero-subtitle-1 { grid-area: 1 / 1 / 2 / 2; }
  .grid_hero > .heading_hero-title      { grid-area: 2 / 1 / 3 / 2; }

  .heading_grid-txt_summary { max-width: 100%; font-size: 24px; line-height: 1.3; }
  .heading_grid-txt_summary.center { font-size: 28px; line-height: 1.3; }
  .heading_grid-txt_summary.dark { font-size: 22px; line-height: 1.3; }
  .heading_grid-txt_subtitle,
  .paragraph_body { max-width: 100%; }
  .paragraph_body.dark { line-height: 170%; }

  .txt_caption {
    margin-top: 20px;
    margin-bottom: 0;
    font-size: 14px;
    line-height: 21px;
    text-align: center;
  }
  .txt_caption.margin-btm { margin-top: 0; margin-bottom: 20px; }

  .txt_link { max-width: 100%; }
}


/* ══════════════════════════════════════════════════════════════
   Project-highlights accordion + full-bleed figures
   Promoted from work-nexus.css once Nexus, IRISe and Roche Data
   Abstraction all needed it. Driven by js/accordion.js.
   ══════════════════════════════════════════════════════════════ */

/* ── Full-bleed figures ───────────────────────────────────── */

.div-img {
  display: block;
  margin-bottom: 0;
}
.div-img.spacing { margin-bottom: 5vh; }

.wrapper.padding-btm { padding-bottom: 100px; }

/* ── Project highlights accordion ─────────────────────────────
   Authored in Webflow as a Tabs widget, but what actually drives it
   is an Interactions (IX2) animation that sets inline
   `height: 0; opacity: 0` on .tab-wrap. All three start collapsed;
   clicking a row expands it to reveal the paragraph and its video.

   Rebuilt here as a real accordion with button semantics and
   aria-expanded — same geometry, keyboard-operable. See js/accordion.js.
   ──────────────────────────────────────────────────────────── */

.tabs-menu {
  display: flex;
  flex-flow: column;
  overflow: visible;
}

.tab-link {
  display: flex;
  width: 100%;
  padding: 9px 0;
  border: 0;
  background-color: #0000;
  color: inherit;
  font: inherit;
  text-align: left;
  text-decoration: none;
  cursor: pointer;
}
.tab-link:focus-visible {
  outline: 2px solid var(--text--secondary);
  outline-offset: 4px;
}

.div-block-103 {
  display: grid;
  grid-template-rows: auto;
  grid-template-columns: auto 1fr;
  grid-column-gap: 16px;
  grid-row-gap: 16px;
  grid-auto-columns: 1fr;
  justify-content: space-between;
  align-items: flex-start;
}

.div-block-104 {
  display: flex;
  justify-content: flex-start;
  align-self: stretch;
  align-items: flex-start;
  width: 32px;
  height: auto;
  padding-top: 2px;
  padding-right: 10px;
}

.div-block-105 {
  display: flex;
  flex-flow: column;
  grid-column-gap: 12px;
  grid-row-gap: 12px;
}

/* Collapsed by default, matching the published page's initial state.
   js/accordion.js animates `height` between 0 and the panel's content. */
.tab-wrap {
  display: flex;
  flex-flow: column;
  grid-column-gap: 20px;
  grid-row-gap: 20px;
  height: 0;
  opacity: 0;
  overflow: hidden;
  transition: height .4s ease, opacity .4s ease;
}
.tab-link[aria-expanded="true"] .tab-wrap { opacity: 1; }

@media (prefers-reduced-motion: reduce) {
  .tab-wrap { transition: none; }
}

.div-video {
  display: block;
  width: auto;
  height: auto;
  margin-bottom: 5vh;
  background-color: #0000;
  object-fit: fill;
}
.div-video.radius {
  flex: 0 auto;
  height: auto;
  border-radius: 10px;
  overflow: clip;
}

@media screen and (max-width: 479px) {
  .tab-wrap {
    display: flex;
    flex-flow: column;
    grid-column-gap: 10px;
    grid-row-gap: 10px;
  }
}

/* An image that opens a prototype. */
.proto-link { display: block; border-radius: 12px; }
.proto-link:focus-visible { outline: 2px solid var(--text--primary); outline-offset: 4px; }

/* ── Password-protected section (js/locked.js, tools/lock.mjs) ──
   The heading and note on the left, the form on the right: the
   2-column layout of the text sections. */
.locked__inner {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  column-gap: 32px;
  row-gap: 32px;
  max-width: 980px;
  margin: 0 auto;
}
.locked__head > * { margin: 0; }
.locked__head > * + * { margin-top: 12px; }
.locked__head a { color: var(--text--primary); text-decoration: underline; text-underline-offset: 3px; }

/* The field and button in the header's dark liquid glass (glass-nav.css
   tokens: fill, blur, shadow), as pills with a plain 1px outline in the
   capsule's rim colour. Submit stays quiet glass while the field is empty
   and turns into a bright pill once something is typed (the field carries
   placeholder=" ", so :placeholder-shown tells empty from filled). A wrong
   password turns the outline red; js/locked.js clears it on input. */
.locked__form { display: grid; gap: 8px; align-content: start; --locked-line: rgba(150, 150, 160, .14); }
.locked__label { margin-bottom: 4px; color: var(--text--primary); font: 700 16px/1.6 Geist, sans-serif; }
.locked__row { display: flex; gap: 8px; }
.locked__input,
.locked__submit {
  height: 44px;               /* the touch-target minimum, lighter than 48 */
  border: 1px solid var(--locked-line);
  border-radius: 999px;
  background-color: var(--glass-fill, rgba(15, 15, 15, .7));
  -webkit-backdrop-filter: var(--glass-filter, blur(16px));
  backdrop-filter: var(--glass-filter, blur(16px));
  box-shadow: var(--glass-shadow, 0 8px 24px rgba(0, 0, 0, .25));
  transition: background-color .2s ease, border-color .2s ease, color .2s ease;
}
.locked__input {
  flex: 1 1 auto;
  min-width: 0;
  padding: 0 16px;
  color: var(--text--primary);
  font: 400 16px/1 Geist, sans-serif;
}
.locked__input:focus { outline: 0; border-color: rgba(150, 150, 160, .5); }
.locked__input[aria-invalid="true"] { border-color: #ff6b6b; }
.locked__submit {
  flex: 0 0 auto;
  padding: 0 20px;
  color: rgba(255, 255, 255, .45);
  font: 500 14px/1 Geist, sans-serif;
  cursor: pointer;
}
.locked__row:has(.locked__input:not(:placeholder-shown)) .locked__submit {
  border-color: var(--text--primary);
  background-color: var(--text--primary);
  color: #000;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}
.locked__row:has(.locked__input:not(:placeholder-shown)) .locked__submit:hover { background-color: #fff; border-color: #fff; }
.locked__submit:disabled { opacity: .6; cursor: progress; }
.locked__submit:focus-visible { outline: 2px solid var(--text--primary); outline-offset: 3px; }
.locked__error { min-height: 1.5em; margin: 0; color: #ff8a8a; font: 400 14px/1.5 Geist, sans-serif; }

@media screen and (max-width: 767px) {
  .locked__inner { grid-template-columns: minmax(0, 1fr); }
}
@media screen and (max-width: 479px) {
  .locked__row { flex-direction: column; }
}
