/* ════════════════════════════════════════════════════════════════════════
   css/work-software-strip.css
   Linked ONLY from work/software.html. Nothing else may link it, and it
   touches no shared stylesheet.

   WHAT IT IS FOR. Two ported components were mounted on the technology
   portfolio and each needs a little page-side chrome that the component's
   own stylesheet deliberately does not own:

     1. js/carousel.js  — the client-build strip. css/components/carousel.css
        owns the viewport, the track and the control bar. It does not own the
        CARD, because a card is page content. The cards here are the same
        .swd blocks the page already had, so the rules below only undo the
        three places where a full-bleed display's geometry is wrong inside a
        368px card.
     2. js/demos.js     — the brief-to-store run. css/components/demos.css
        owns .tdx-stage and everything inside the demo. It does NOT style
        .tdx-row, by design: the disclosure chrome belongs to the page.

   TOKEN BRIDGE (PORTED-COMPONENTS.md rule 5). Every custom property read
   below is declared at :root by css/work.css, which this page links first.
   The --ws-* family re-declares them with literal fallbacks so a future page
   that mounts either component without work.css cannot render in the browser
   default serif.

   PREFIXED, because `--mono: var(--mono, …)` is a self-reference: a custom
   property may not appear in its own value, so that declaration resolves to
   the guaranteed-invalid value and the token is LOST rather than bridged.
   css/components/demos.css uses the same --dx-* pattern for the same reason.
   ════════════════════════════════════════════════════════════════════════ */

:root {
  --ws-mono: var(--mono, 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace);
  --ws-bone: var(--bone, #f5f1e8);
  --ws-red:  var(--red-ink, #ef5c6e);
  --ws-dim:  var(--dim-ink, #8b847c);
  --ws-line: var(--hair-ink, rgba(245, 241, 232, .14));
  --ws-plate: var(--plate, #121212);
  --ws-ease: var(--ease, cubic-bezier(.2, .7, .2, 1));
}

/* ── THE DISCLOSURE ROW ───────────────────────────────────────────────────
   The rebuild's disclosure primitive: a real <details>, so it opens with no
   JS, is keyboard operable for free, and its collapsed text stays findable by
   the browser's own find-in-page. js/demos.js only READS the open state — it
   never opens or closes the element — so the disclosure and the demo inside
   it cannot fight each other.

   Copied from __ported-demos.html rather than reinvented, so every page that
   mounts a demo has the same summary. */
.tdx-row { border-top: 1px solid var(--ws-line); }
.tdx-row > summary {
  list-style: none;
  cursor: pointer;
  padding: 1.1rem 0;
  display: flex;
  gap: 1rem;
  align-items: baseline;
  font-family: var(--ws-mono);
  font-size: .78rem;
  letter-spacing: .06em;
  color: var(--ws-bone);
}
.tdx-row > summary::-webkit-details-marker { display: none; }
.tdx-row > summary b { color: var(--ws-red); font-weight: 500; }
.tdx-row > summary:focus-visible { outline: 2px solid var(--ws-red); outline-offset: 2px; }
.tdx-row__panel { padding: 0 0 2.4rem; }

/* The one line under the run. Not a restatement of it — a route out. */
.tdx-row__out {
  margin: 1.4rem 0 0;
  font-family: var(--ws-mono);
  font-size: .75rem;
  color: var(--ws-dim);
}

@media (hover: hover) and (pointer: fine) {
  .tdx-row > summary { transition: color .2s var(--ws-ease); }
  .tdx-row > summary:hover { color: var(--ws-bone); }
}

/* ── THE CLIENT-BUILD STRIP ───────────────────────────────────────────────
   The eight client builds were eight full-width displays in a vertical
   stack. Measured in Chrome at 1440 on 2026-08-21, that stack was 7,859px
   of a 13,786px page — 57% of the whole document was one section, and a
   reader had to scroll past four builds to learn that a fifth existed.
   PORTED-COMPONENTS.md names this exact shape as the carousel's job.

   NOTHING LEFT THE DOM. Every card keeps its own capture, index, kind,
   name, sector, status, description, technology list, deep-link id and
   outbound link. The cards are authored in the served HTML, in order, so a
   crawler reads all eight and find-in-page finds all eight. The strip only
   changes the axis they are laid out on. */

/* .carou__item is display:flex from the component; the card has to fill it. */
.carou__item > .swd {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  border: 1px solid var(--ws-line);
  background: var(--ws-plate);
}

/* The frame's own border would double the card's, and its overflow already
   clips the capture. */
.carou__item .swd__frame { border: 0; border-bottom: 1px solid var(--ws-line); }

/* THREE OVERRIDES, and only three.

   min-height on .swd__label existed so a column of eight full-width
   displays kept one rhythm whether or not the optional copy arrived. In a
   strip the cards are side by side and equal-height already, so the floor
   only adds dead space under the shortest card.

   max-width: 68ch on .swd__desc is a measure for a full-bleed paragraph. In
   a 368px card it never binds, and leaving it in invites a future reader of
   this file to think the card is 68 characters wide.

   The label needs padding now that the card has a border. */
.carou__item .swd__label {
  min-height: 0;
  padding: 1.15rem clamp(1rem, 3vw, 1.35rem) clamp(1.2rem, 3vw, 1.5rem);
  flex: 1 1 auto;
}
.carou__item .swd__desc {
  max-width: none;
  margin-top: .7rem;
  font-size: .875rem;
  line-height: 1.58;
}
.carou__item .swd__title { font-size: clamp(1.15rem, 2.4vw, 1.45rem); }
.carou__item .swd__meta  { margin-top: .4rem; }
.carou__item .swd__stack { margin-top: .8rem; }

/* The outbound link is the card's action and belongs at its foot, on the
   baseline, however short the description above it is. */
.carou__item .swd__out { margin-top: auto; padding-top: 1.1rem; }

/* The plate's title is set at display size for a 1136px frame. At 368px it
   would break out of its own plate. */
.carou__item .swd__plateTitle { font-size: clamp(1.1rem, 4vw, 1.5rem); }

/* THE STRIP IS THE START STATE'S UNIT, NOT THE CARD. The page's reveal
   (html.sw-anim in css/work-software.css) arms [data-rise] at opacity 0 and
   an IntersectionObserver clears it. A card that is scrolled off the RIGHT
   edge of a horizontal viewport is never sampled by that observer, so it
   would stay invisible for the session — the same fault the page's own
   safety net exists to catch, arriving by a different door. So no card
   carries [data-rise]; the strip carries one, and reveals as a unit. */

/* ── REDUCED MOTION ───────────────────────────────────────────────────────
   js/carousel.js already drops its smooth scroll to `auto` and reads the
   setting live on every press. Nothing here animates position, so there is
   nothing further to switch off; the hover transitions above are the only
   motion and they are removed with the rest of the page's in css/work.css. */

/* ── THE DEMO FAMILY IN S.03 ──────────────────────────────────────────────
   Added 2026-08-22 with the three ported mechanics (rls, pay, job) that
   replaced the register's un-showable claims.

   It is deliberately a .sysfam like the four families above it, so "How they
   work" sits under the same red rule as PUBLISHING, PRODUCTION, CLIENTS AND
   MONEY and PLATFORM, and the section reads as one register rather than a
   list with an appendix bolted on. The only differences are the two below.

   1. NO DOUBLED RULE. .sysfam__hd draws a red border-bottom and .tdx-row
      draws its own hairline border-top, so the first disclosure under the
      heading would sit on two lines 1px apart. The families above avoid it
      because .sysfam__list > li is border-BOTTOM only. */
.sysfam--demo > .tdx-row:first-of-type { border-top: 0; }

/* 2. THE PANEL BREATHES ON THE HEADING SIDE. .tdx-row__panel is bottom-padded
      only, which is right in S.01 where the run is the last thing in its
      band. Here three of them stack, so an open panel would otherwise touch
      the summary of the row beneath it. */
.sysfam--demo .tdx-row__panel { padding-top: .35rem; }

/* The last row closes the family the way .sysfam__list > li does, so the
   block does not end on open space. */
.sysfam--demo > .tdx-row:last-of-type { border-bottom: 1px solid var(--ws-line); }

/* ── THE CRON RULER AT PHONE WIDTH ────────────────────────────────────────
   Measured in Chrome at 390 on 2026-08-22: the lane-label column takes
   7.8rem of a 390px viewport, leaving the track 225px to carry five 32px
   time labels — 160px of text in 225px of rail. Nothing overlapped and
   nothing lied (every marker centre still matched its authored --at to the
   decimal, and 00:00 / 24:00 are the two anchors that fix the scale), but
   06:00 and 18:00 were crowding their neighbours to no purpose: they are
   scale furniture, not data.

   So they are dropped below 480px, which is the same call css/components/
   demos.css already makes for the payment node labels at 460px, and for the
   same reason. 00:00, 12:00 and 24:00 still fix the axis.

   SCOPED TO THIS PAGE'S OWN CLASS, not to .job__ruler span, so no other page
   that mounts the cron demo is changed by this file. The two spans keep
   their inline left, so nothing about the geometry moves. */
@media (max-width: 480px) {
  .job__tick--mid { display: none; }
}
