/* ============================================================
   Hocus — page-specific sheet. The frame (side index, content
   column, eyebrow and claim type, footer) comes from
   case-study.css; this adds what a concept case study needs and
   the Miivo page does not: labelled media slots, numbered steps,
   decision rows, a comparison table and a research disclosure.

   Every media slot on this page is a stand-in. The project is a
   self-initiated concept, so the grey rectangles are honest
   about what exists rather than dressed up as screenshots.
   ============================================================ */

/* Keeps the last line of a paragraph or heading from ending on one stranded
   word. The browser balances the final lines instead of filling greedily. */
.content { text-wrap: pretty; }

/* ── Section openings ──────────────────────────────────── */

/* The hero carries a project label above it, which the Miivo hero does not.
   It takes the same step an eyebrow takes above a claim there. */
.eyebrow + .hero__title { margin-top: 14px; }

/* An eyebrow that opens a second division inside one section steps down by a
   full block, the same distance that separates two sections. */
.eyebrow--divide { margin-top: var(--block); }

/* Its paragraph follows at the label's own step, not the imagery step. */
.eyebrow + .section__body { margin-top: 14px; }

/* ── Media slots ───────────────────────────────────────── */

/* One component for all twelve slots. The ratio is passed per slot, since
   the shape of each intended asset differs and the page should hold the
   right amount of space for it. */
.slot { margin: var(--inner) 0 0; }

.slot__fill {
  aspect-ratio: var(--ratio, 16 / 9);
  background: var(--shot);
  border-radius: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
}

/* The label describes the asset that belongs here. Kept to a readable
   measure and centred, so a wide slot doesn't stretch it into one long line. */
.slot__label {
  max-width: 34ch;
  font-size: 13px;
  font-weight: 500;
  line-height: 165%;
  text-align: center;
  color: #6E6E6E;
}
.slot__label b {
  display: block;
  margin-bottom: 4px;
  font-family: var(--eyebrow-face);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: #8A8A8A;
}

/* A mount: the slot keeps its grey and the artefact sits inset within it,
   the way the Miivo showcases hold a screen recording. A white interface
   needs the surround, where a product render fills the slot edge to edge. */
.slot__mount {
  aspect-ratio: var(--ratio, 16 / 9);
  /* Lighter than the placeholder grey: enough to separate a white interface
     from the page, without the artefact sitting in a dark well. */
  background: #E8E8E8;
  border-radius: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
}
/* Scoped to the mount so it outranks the fill-the-slot rule below, which
   would otherwise stretch this to the mount's own shape and crop the sides. */
.slot__mount .slot__video--inset {
  width: 84%;
  height: auto;
  aspect-ratio: 1996 / 1080;
  object-fit: contain;
  border-radius: 6px;
  border: 1px solid var(--hairline);
}

/* A real asset in a slot keeps the slot's shape and rounding, so a filled
   slot and a placeholder still sit on the same rhythm. */
.slot__img,
.slot__video {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: var(--ratio, 16 / 9);
  object-fit: cover;
  border-radius: 8px;
  background: var(--shot);
}

.slot__caption {
  margin-top: 14px;
  font-size: 13px;
  font-weight: 500;
  line-height: 160%;
  color: var(--ink-faint);
}

/* Two slots that belong to the same comparison sit in one row and keep one
   caption each, so the before and after read against each other. */
.slot-pair {
  margin-top: var(--inner);
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 20px;
}
.slot-pair .slot { margin-top: 0; }

/* Keeps the last line of a paragraph or heading from ending on one stranded
   word. The browser balances the final lines instead of filling greedily. */
.content { text-wrap: pretty; }

/* ── Section openings ──────────────────────────────────── */

/* case-study.css sets the line under a claim at 16px/150%, a step above the
   body — it reads as a second headline. On this page it is the paragraph
   belonging to the h2, so it takes the same setting as every other paragraph
   here and the two together read as one heading and its text. */
.claim + .section__lede,
.lead + .section__lede {
  font-size: 15px;
  line-height: 170%;
}
.lead + .section__lede { margin-top: 18px; }

/* ── Parts strip ───────────────────────────────────────── */

/* Names the physical parts of the dock directly beneath it. Every other
   section on this page argues; this one is introducing an object, and a row
   of parts is how an object gets introduced. Kept to plain labels at eyebrow
   weight so it reads as a caption to the hardware, not a feature list. */
/* A second paragraph in a section, after the imagery that broke the first
   one off. Same setting as the lede, spaced like a block rather than a line. */
.section__body {
  margin-top: var(--inner);
  font-size: 15px;
  font-weight: 500;
  line-height: 170%;
  color: var(--ink-muted);
}

/* ── Overview brief ────────────────────────────────────── */

/* The four tiles here hold a few words each, not the sentences the Miivo
   brief carries, so the value can be set larger and read as the answer to
   its label rather than as a note beneath it. */
.meta__copy {
  font-size: 17px;
  line-height: 150%;
}

/* ── Companion carousel ────────────────────────────────── */

/* Four screens on one grey mount, scrolled horizontally. The screenshots run
   wider here than the recording above them: a still can take the extra size
   where a playing video would dominate the section. */
.carousel { margin-top: 14px; }

.carousel__track {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 100%;
  gap: 14px;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;          /* the dots below are the affordance */
}
.carousel__track::-webkit-scrollbar { display: none; }
.carousel__track:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; }

.carousel__slide {
  margin: 0;
  scroll-snap-align: start;
  background: #E8E8E8;
  border-radius: 8px;
  padding: 26px;
}
/* The screen is a button so a tap and the keyboard both open the viewer. It
   carries no button styling of its own; the image is the control. */
.carousel__zoom {
  display: block;
  width: 100%;
  padding: 0;
  border: 0;
  background: none;
  cursor: zoom-in;
  border-radius: 6px;
}
.carousel__zoom:focus-visible { outline: 2px solid var(--ink); outline-offset: 4px; }

.carousel__slide img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 1770 / 1001;
  border-radius: 6px;
  border: 1px solid var(--hairline);
}

/* ── Enlarged view ─────────────────────────────────────── */

.zoom {
  width: 100vw;
  max-width: 100vw;
  height: 100vh;
  max-height: 100vh;
  padding: 0;
  border: 0;
  background: transparent;
  overscroll-behavior: contain;
}
.zoom::backdrop { background: rgba(0, 0, 0, .78); }

.zoom[open] {
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: zoom-out;
}
.zoom__img {
  max-width: min(1400px, 94vw);
  max-height: 90vh;
  width: auto;
  height: auto;
  border-radius: 8px;
  cursor: default;
}

.zoom__close {
  position: fixed;
  top: 22px;
  right: 22px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: rgba(255, 255, 255, .14);
  color: #fff;
  cursor: pointer;
  transition: background .3s var(--ease);
}
.zoom__close:hover { background: rgba(255, 255, 255, .26); }
.zoom__close:focus-visible { outline: 2px solid #fff; outline-offset: 3px; }

.carousel__dots {
  margin-top: 16px;
  display: flex;
  justify-content: center;
  gap: 8px;
}
.carousel__dot {
  width: 7px;
  height: 7px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: var(--shot);
  cursor: pointer;
  transition: background .3s var(--ease);
}
.carousel__dot[aria-current="true"] { background: var(--ink-muted); }
.carousel__dot:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; }

/* ── Bento ─────────────────────────────────────────────── */

/* Three views of the object in one row, with the mark in the middle and a
   product shot either side. The columns are sized to each image's own
   proportions rather than split into equal thirds, so all three stand at the
   same height with nothing cropped to fit. */
.bento {
  margin-top: 14px;
  display: grid;
  grid-template-columns: 1.4019fr 0.9772fr 1.3346fr;
  gap: 14px;
}
.bento__cell {
  margin: 0;
  border-radius: 8px;
  overflow: hidden;
  background: var(--card);
}
.bento__cell img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.bento__cell--detail { aspect-ratio: 1200 / 856; }
.bento__cell--mark   { aspect-ratio: 900 / 921; }
.bento__cell--angle  { aspect-ratio: 1400 / 1049; }

/* A closed grid: ruled on all four sides with a division between every cell,
   so the parts read as one table of the hardware rather than a row of notes
   under the photograph. */
.specs {
  margin-top: 32px;
  padding: 0;
  list-style: none;
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  border: 1px solid var(--hairline);
  border-radius: 8px;
  overflow: hidden;   /* the corner cells clip to the radius */
}
.specs__item {
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding: 26px 18px 28px;
  font-family: var(--eyebrow-face);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: .07em;
  line-height: 150%;
  text-transform: uppercase;
  color: var(--ink);
  border-right: 1px solid var(--hairline);
}
.specs__item:last-child { border-right: 0; }

/* Line drawings of the parts themselves. Sized well above label height and
   inked at the body grey, so they carry the cell rather than sit in it. */
.specs__icon {
  flex-shrink: 0;
  width: 28px;
  height: 28px;
  color: var(--ink-muted);
}

/* ── Why physical ──────────────────────────────────────── */

/* The photograph carries the argument, so it leads and the claim sits beside
   it rather than above the whole section. The text sits on the image's bottom
   edge: one line across the two columns reads as deliberate, where a centred
   block of a different height does not. */
.physical {
  margin-top: 14px;
  display: grid;
  grid-template-columns: 1fr 1.1fr;
  gap: 30px;
  align-items: end;
}
.physical__shot { margin: 0; }
.physical__shot img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  border-radius: 8px;
}
.physical__text .claim { margin-top: 0; }

/* ── Text column groups ────────────────────────────────── */

/* Two, three or four short columns under one claim. --n carries the count so
   the same component covers every group on the page. */
.cols {
  margin-top: var(--inner);
  display: grid;
  grid-template-columns: repeat(var(--n, 2), minmax(0, 1fr));
  gap: 30px;
}
/* Boxed columns. Each point sits in its own tile on the house card grey, the
   same shape the brief tiles use on the Miivo overview. Grid stretch keeps
   every tile the height of the tallest, so the row reads as one band rather
   than four cards of different depths. */
.cols--boxed {
  gap: 12px;
}
.cols--boxed > * {
  background: var(--card);
  border-radius: 8px;
  padding: 20px;
}

/* A group left with one column runs the full width, so its paragraph takes
   the page's body setting rather than the tighter column setting. */
.cols--solo .col__copy {
  font-size: 15px;
  line-height: 170%;
}

.cols--tight { margin-top: 32px; }
/* A slot placed inside a column group is already spaced by the grid. */
.cols .slot { margin-top: 0; }

.col__title {
  font-size: 16px;
  font-weight: 600;
  letter-spacing: -.015em;
  line-height: 145%;
  color: var(--ink);
}
.col__copy {
  margin-top: 10px;
  font-size: 14px;
  font-weight: 500;
  line-height: 172%;
  color: var(--ink-muted);
}
/* A card carrying only a paragraph needs no offset from a heading above it. */
.col__copy:first-child { margin-top: 0; }

/* Where the heading has been folded into the sentence, the paragraph takes
   the heading's setting: it is the statement, not a note beneath one. */
.cols--stated .col__copy {
  font-size: 16px;
  font-weight: 600;
  letter-spacing: -.015em;
  line-height: 150%;
  color: var(--ink);
}

.col__copy + .col__copy { margin-top: 14px; }

/* A second heading stacked inside one column opens a new point, so it takes
   the group step rather than the paragraph step. */
.col__copy + .col__title { margin-top: 32px; }
.eyebrow + .col__title { margin-top: 14px; }

/* ── Quiet notes ───────────────────────────────────────── */

/* Audience notes, trade-offs and caveats. They carry the limits of the work,
   so they are set apart from the argument without being buried. */
.note {
  margin-top: 32px;
  background: var(--card);
  border-radius: 8px;
  padding: 22px 24px;
  font-size: 14px;
  font-weight: 500;
  line-height: 172%;
  color: var(--ink-muted);
}
.note strong {
  display: block;
  margin-bottom: 5px;
  font-weight: 600;
  color: var(--ink);
}

/* ── Workflow steps ────────────────────────────────────── */

.step { margin-top: var(--block); }
.step__title {
  margin-top: 14px;
  font-size: 20px;
  font-weight: 500;
  line-height: 148%;
  color: var(--ink);
}
.step__copy {
  margin-top: 14px;
  font-size: 15px;
  font-weight: 500;
  line-height: 172%;
  color: var(--ink-muted);
}
.step__copy em {
  font-style: normal;
  color: var(--ink);
}

/* ── Decision rows ─────────────────────────────────────── */

/* A short heading on the left, the reasoning and its cost on the right. The
   trade-off is part of the row rather than a footnote: leaving something out
   is only a decision if what it costs is stated. */
.rows {
  margin-top: var(--inner);
  display: flex;
  flex-direction: column;
  gap: 12px;
}

/* Each decision is its own card. Outlined rather than filled: the boxed
   groups elsewhere on the page carry the card grey, and four filled blocks
   in a row would read as heavier than the argument they hold. */
.row {
  display: grid;
  grid-template-columns: 280px minmax(0, 1fr);
  gap: 0 40px;
  padding: 24px;
  border: 1px solid var(--hairline);
  border-radius: 10px;
}

/* A cross, because the section is about what was left out. It sits inside the
   card above the title: on the corner it broke the card's outline and ran
   into the column beside it. */
/* The mark and the title read as one line: what was cut, with the cross
   marking it. The reasoning sits opposite in its own column. */
.row__head {
  display: flex;
  align-items: center;
  gap: 12px;
}

.row__mark {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 26px;
  height: 26px;
  border-radius: 7px;
  background: rgba(214, 69, 52, .1);
  color: #D64534;
}

.row__title {
  font-size: 17px;
  font-weight: 600;
  letter-spacing: -.015em;
  line-height: 145%;
  color: var(--ink);
}
.row__copy {
  font-size: 15px;
  font-weight: 500;
  line-height: 172%;
  color: var(--ink-muted);
}
.row__copy strong { font-weight: 600; color: var(--ink); }

.row__tradeoff {
  margin-top: 14px;
  font-family: var(--eyebrow-face);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: .06em;
  text-transform: uppercase;
  line-height: 160%;
  color: var(--ink-faint);
}

/* ── Comparison table ──────────────────────────────────── */

.table { margin-top: var(--inner); }
.table__row {
  display: grid;
  grid-template-columns: 280px minmax(0, 1fr);
  gap: 0 40px;
  padding: 20px 0;
  box-shadow: inset 0 -1px 0 var(--hairline);
}
.table__head {
  padding-bottom: 12px;
  box-shadow: inset 0 -1px 0 var(--ink);
}
.table__head p {
  font-family: var(--eyebrow-face);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--ink);
}
.table__key {
  font-size: 16px;
  font-weight: 600;
  letter-spacing: -.015em;
  color: var(--ink);
}
.table__val {
  font-size: 15px;
  font-weight: 500;
  line-height: 172%;
  color: var(--ink-muted);
}

/* ── Research disclosure ───────────────────────────────── */

/* Collapsed by default. The sources explain where the thinking came from;
   they are not evidence that the concept works, and the closing paragraph
   inside says so. */
.research {
  margin-top: 32px;
  border-radius: 8px;
  background: var(--card);
  padding: 4px 24px;
}
.research__summary {
  padding: 18px 0;
  cursor: pointer;
  list-style: none;
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 15px;
  font-weight: 600;
  letter-spacing: -.015em;
  color: var(--ink);
}
.research__summary::-webkit-details-marker { display: none; }
.research__summary::after {
  content: '';
  width: 7px;
  height: 7px;
  margin-left: auto;
  border-right: 1.4px solid var(--ink-muted);
  border-bottom: 1.4px solid var(--ink-muted);
  transform: rotate(45deg) translate(-2px, -2px);
  transition: transform .3s var(--ease);
}
.research[open] .research__summary::after {
  transform: rotate(225deg) translate(-2px, -2px);
}
.research__summary:focus-visible { outline: 2px solid var(--ink); outline-offset: 4px; }

.research__body {
  padding: 0 0 22px;
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.research__body p {
  font-size: 14px;
  font-weight: 500;
  line-height: 175%;
  color: var(--ink-muted);
}
.research__body a {
  color: var(--ink);
  text-decoration: underline;
  text-underline-offset: 2px;
  text-decoration-thickness: 1px;
}

/* ── Pull quote and closing ────────────────────────────── */

/* Both run the full content column, like every other block on the page: the
   media slots set one left and right edge and the text holds to it. */
/* Opening a section, the question sits under its label like a claim does. */
.eyebrow + .pull { margin-top: 14px; }

.pull,
.lead {
  margin: var(--block) 0 0;
  font-size: clamp(22px, 2.6vw, 30px);
  font-weight: 500;
  letter-spacing: -.02em;
  line-height: 140%;
  color: var(--ink);
}

/* The claim and the supporting line are folded into one sentence, read at a
   single weight, with only the section label standing above it. */
.lead { margin-top: 0; }
.eyebrow + .lead { margin-top: 14px; }

.closing {
  margin-top: var(--block);
  font-size: clamp(24px, 3.2vw, 38px);
  font-weight: 500;
  letter-spacing: -.02em;
  line-height: 130%;
  color: var(--ink);
}
.closing em { font-style: italic; color: var(--ink-muted); }

/* ── Responsive ────────────────────────────────────────── */

@media (max-width: 860px) {
  .cols { --n: 2 !important; }
  .row,
  .table__row { grid-template-columns: 1fr; gap: 10px; }
  .row__title, .table__key { font-size: 16px; }
  .table__head { display: none; }
}

@media (max-width: 700px) {
  .cols { --n: 1 !important; gap: 20px; }

  /* Same step-down as the case-study sheet: these were sized against the
     desktop column. */
  .lead { font-size: 19px; line-height: 136%; }
  .pull { font-size: 19px; line-height: 138%; }
  .closing { font-size: 22px; }
  .col__title { font-size: 15px; }

  /* Matches the case-study sheet: one reading size, one label size. The
     section body sits a step above the rest: it carries the argument, the
     others carry the detail around it. */
  .section__body,
  .claim + .section__lede,
  .lead + .section__lede { font-size: 14px; line-height: 172%; }

  .section__lede,
  .col__copy,
  .row__copy,
  .step__copy,
  .spec__copy,
  .cols--stated .col__copy { font-size: 13px; line-height: 178%; }

  .slot__caption,
  .spec__title { font-size: 12px; }

  /* Same inversion as .showcase__title on the case-study sheet. */
  .step__title { font-size: 16px; line-height: 140%; }

  /* Five columns at this width gives each part 65px, which breaks
     "dot-matrix timer" over three lines and pushes "five-button grid" past
     the edge. Two across instead, with the fifth taking the full last row.
     The single right-hand border becomes a border on every cell, cancelled
     at the end of each row and on the last row, so the rules still meet. */
  .specs { grid-template-columns: 1fr 1fr; }
  .specs__item {
    padding: 18px 14px 20px;
    gap: 12px;
    border-right: 1px solid var(--hairline);
    border-bottom: 1px solid var(--hairline);
  }
  .specs__item:nth-child(2n) { border-right: 0; }
  .specs__item:last-child {
    grid-column: 1 / -1;
    border-right: 0;
    border-bottom: 0;
  }

  /* The recordings already carry their own rounded corners, so the slot's
     8px clipped a second curve over the first. A hairline radius is enough
     to keep the frame from reading as a hard-cut rectangle. */
  .slot__img,
  .slot__video { border-radius: 4px; }
  .slot__mount { border-radius: 4px; }

  /* The first two share a row rather than stacking: at full width the detail
     and the mark each take most of a screen for what is a supporting pair.
     They carry their own aspect ratios, so the row is squared off by forcing
     both to the same one. The third keeps the full width below them. */
  .bento { grid-template-columns: 1fr 1fr; gap: 10px; }
  .bento__cell--detail,
  .bento__cell--mark { aspect-ratio: 1 / 1; }
  .bento__cell--angle { grid-column: 1 / -1; }

  /* This sheet sets the brief's value at 17px, which reads as the answer to
     its label across a desktop tile. Stacked one per row on a phone it is
     the largest body text on the page and outruns the section claims. */
  .meta__copy { font-size: 14px; line-height: 155%; }

  .physical { grid-template-columns: 1fr; gap: 24px; }
  .slot-pair { grid-template-columns: 1fr; gap: 24px; }
  .note { padding: 18px 20px; }
  .research { padding: 4px 20px; }
}
