/* ════════════════════════════════════════════════════════════════════════
   css/stack.css — /stack ONLY
   service.tnaado.ca · loaded after css/reference.css, css/components/demos.css
   and css/aux-pages.css, before css/chrome.css.

   WHY THIS SHEET EXISTS, in two parts.

   1. THE GROUND. Ethan: "needs more white". reference.css's own header already
      argued the case — "a stranger arriving from a search result or an ad needs
      the answer, not a wait" — and then handed all five reference pages an ink
      ground anyway, with .on-bone reserved for one band per page. /stack is the
      most reference-like of the five: it is a list of platform names a technical
      buyer scans. So the ground flips. Bone page, white cells, ink type.

      TWO SECTIONS STAY DARK, on purpose, and neither is a compromise:
        · S.02 "Running" — css/components/demos.css is authored bone-on-ink and
          has no on-bone modifier (the /shopify build recorded the same thing
          about its own component). Recolouring it from here would mean writing
          overrides for .rls, .pay, .mig and .job in a sheet that does not own
          them. The demos are a terminal, a payment log and a migration list;
          a dark stage is where those belong anyway.
        · S.05 the close — .close is ink in reference.css and css/chrome.css
          draws .footpull with a rgba(10,10,10,.92) scrim over whatever is
          beneath it. Keeping the last section ink keeps that scrim correct and
          means this page never needs data-foot="light", which would have to be
          written inside the SVC-CHROME:FOOT markers.

      EVERYTHING IS SCOPED UNDER .stack-page ON <body>. Nothing in this file can
      reach another page even though .on-bone, .crumb, .band and .axset are all
      shared classes. That is deliberate: the alternative was editing
      reference.css and aux-pages.css, which nineteen other pages read.

   2. THE MARKS. The page had two <img> and zero <svg> on it — no tool logos at
      all. .tgrid below is the replacement. It is a fresh component rather than
      a reskin of reference.css's .stack, because .stack__cell is --plate #0d0d0d
      and every rule in it is written for ink.

      LICENCE POSITION, decided from the vendors' own pages, not from memory:
        · The thirteen glyphs are Simple Icons' single-path monochrome redraws,
          the icon files under CC0-1.0 whose §4.1 keeps every trademark with its
          owner. One colour, one 24-unit box, uniform clear space — which is
          also what the vendors that publish a one-colour mark ask for.
        · APPLE AND SWIFT GET NO GLYPH. Apple's Guidelines for Using Apple
          Trademarks: "You may not use the Apple Logo or any other Apple-owned
          graphic symbol, logo, or icon on or in connection with web sites …
          except pursuant to an express written trademark license from Apple."
          The Swift bird is an Apple-owned graphic symbol. The same page allows
          the WORD marks in a referential phrase, so those two are set in type.
        · THE SIX GOOGLE PRODUCTS GET NO GLYPH. Google's brand-elements page:
          "Don't combine your logo with the Google G or modify the Google G in
          any way, including changing the color." A monochrome redraw changes
          the colour. Google publishes no one-colour variant, so the compliant
          options were full colour or type, and eight full-colour four-colour
          marks in a wall of monochrome is the clashing palette the brief warned
          about. Type it is.
      So .tgrid__mono is not a fallback for a mark that could not be found. It
      is the treatment for the eight names whose owners do not permit the mark
      this page would need.
   ════════════════════════════════════════════════════════════════════════ */

.stack-page {
  /* The one new value in this sheet. #fff already appears in reference.css
     (.btn--go:hover), but nothing there names it, and the cells need a plate
     that reads as lighter than the --bone #f5f1e8 ground behind them. */
  --paper: #fff;
  background: var(--bone);
  color: var(--ink);
}


/* ══ THE BONE GROUND, AND THE FOUR GAPS IN .on-bone ═══════════════════════
   .on-bone in reference.css covers headings, .lede, .copy, .note, .card,
   .grid, .btn, .mailto, .stamp and .deriv. It does not cover the breadcrumb,
   the band separator, a bare <b>, or aux-pages.css's .axset — because until
   now no page put those on a bone ground. Patched here, page-scoped. */

.stack-page .on-bone { background: var(--bone); }

/* The breadcrumb is --dim-ink #b9b3a6, which is 9.4:1 on ink and 1.9:1 on
   bone. On a bone hero it was unreadable and the current page was invisible. */
.stack-page .on-bone .crumb a { color: var(--ink-2); }
.stack-page .on-bone .crumb a:hover { color: var(--ink); }
.stack-page .on-bone .crumb [aria-current] { color: var(--ink); }
.stack-page .on-bone .crumb li + li::before { color: var(--red-bone); }

/* .band + .band draws rgba(245,241,232,.14) — invisible between two bone
   bands, and wrong above the one ink band.

   :not(.band--ink) IS LOAD-BEARING. Without it this rule beat the red rule on
   the ink band and won on specificity, not order: `.stack-page .band + .band`
   counts THREE classes, `.stack-page .band--ink` counts two. Measured before
   the fix — #running resolved to border-top: 2px rgba(10,10,10,.16), the red
   width with the hairline's colour. Both bands are excluded rather than
   answered with a second rule, because a second rule needed matching
   specificity too and the hairline under the ink band's red bottom rule was
   MEASURED as a doubled line: 2px #c8102e with a 1px rgba(10,10,10,.16)
   immediately under it. One selector, no conflict. */
.stack-page .band:not(.band--ink) + .band:not(.band--ink) {
  border-top-color: var(--hair-bone);
}

/* reference.css: strong, b { color: var(--bone) }. */
.stack-page .on-bone b,
.stack-page .on-bone strong { color: var(--ink); }

/* aux-pages.css keys its bone variants off .fp-band--bone, a class defined in
   css/firm-pages.css — a sheet this page does not load. Mirrored rather than
   borrowed, so the class on the markup means what it says. */
.stack-page .on-bone .axset { border-color: var(--hair-bone); }
.stack-page .on-bone .axset__h { color: var(--red-bone); }
.stack-page .on-bone .axset__chips > li {
  border-color: var(--hair-bone); color: var(--ink);
}

/* The one band that stays dark. Body is bone now, so this has to be said. */
.stack-page .band--ink { background: var(--ink); color: var(--bone); }

/* S.04's three cards. reference.css gives .on-bone .card a rgba(10,10,10,.04)
   plate, which composites to #ece8df — MEASURED, and against the white cells of
   the grid above it that read as a muddy grey block on a page whose whole ask
   was more white. Same paper as the grid cells, same hairline, so the two
   figures on the page are made of the same material. Contrast re-measured in
   the browser on #fff: .card h3 at --ink 19.8:1, .card p at --ink-2 12.0:1,
   .card__kicker at --red-bone 7.75:1. */
.stack-page .on-bone .card { background: var(--paper); }
.stack-page .on-bone .card__kicker { color: var(--red-bone); }

/* And the same empty-track fault .tgrid was rebuilt to avoid, because .grid
   uses the same gap: 1px technique. MEASURED at 760px: three cards over two
   columns, and the fourth track rendered as a 350x150 rgba(10,10,10,.16) block.
   Same cure — the rules move onto the cells. */
.stack-page .on-bone .grid {
  gap: 0; background: none;
  border: 0;
  border-top: 1px solid var(--hair-bone);
  border-left: 1px solid var(--hair-bone);
}
.stack-page .on-bone .grid > .card {
  border-right: 1px solid var(--hair-bone);
  border-bottom: 1px solid var(--hair-bone);
}


/* ══ THE PLATFORM GRID ════════════════════════════════════════════════════
   One cell per platform: the mark, the name, and one line on what it is for.
   auto-fit with a 15rem floor, so a group of three and a group of seven both
   fill their row instead of leaving four empty cells at the end.

   NOT INTERACTIVE. No cell is a link — there is no per-platform page to send a
   reader to and inventing one is not allowed — so there is no touch target
   here to hold to the 44px floor, and the pointer response is a background
   change with no transform. */

.tgroup {
  display: flex; align-items: baseline; gap: .75rem;
  margin: clamp(1.75rem, 3.5vw, 2.5rem) 0 .9rem;
  font-family: var(--mono); font-weight: 500; font-size: .75rem;
  letter-spacing: .16em; text-transform: uppercase; color: var(--ink-2);
}
.tgroup::after {
  content: ''; flex: 1 1 auto; height: 1px; background: var(--hair-bone);
}

/* THE HAIRLINES ARE ON THE CELLS, NOT IN THE GAP. reference.css's .stack drew
   them the usual way — gap: 1px over a background — and that technique paints
   any EMPTY tail track in the gap colour. MEASURED at 1440: the seven-cell
   group wrapped to 4 + 3 and the fourth track of the second row rendered as a
   solid rgba(10,10,10,.16) block, which reads as a broken cell. The grid
   supplies the top and left rule and each cell supplies its own right and
   bottom, so there is no doubling anywhere and an unfilled track paints
   nothing. The groups are also sized 4/4/3/4/3/4 so no row is ragged at the
   four-column width. */
.tgrid {
  display: grid; gap: 0; margin: 0;
  grid-template-columns: repeat(auto-fit, minmax(min(15rem, 100%), 1fr));
  border-top: 1px solid var(--hair-bone);
  border-left: 1px solid var(--hair-bone);
}
.tgrid__cell {
  background: var(--paper);
  border-right: 1px solid var(--hair-bone);
  border-bottom: 1px solid var(--hair-bone);
  padding: 1.1rem 1.25rem 1.25rem;
}
@media (hover: hover) and (pointer: fine) {
  .tgrid__cell { transition: background-color .18s var(--ease); }
  .tgrid__cell:hover { background: var(--bone-2); }
}
@media (prefers-reduced-motion: reduce) {
  .tgrid__cell { transition: none; }
}

/* THE MARK WELL. One 1.75rem box on every cell, whichever treatment fills it,
   so the names line up down the column and the grid does not look half-built
   where a mark is not permitted. */
.tgrid__mark {
  display: flex; align-items: center; justify-content: flex-start;
  height: 1.75rem; margin: 0 0 .8rem;
}
.tgrid__mark svg {
  display: block; width: 1.375rem; height: 1.375rem;
  fill: var(--ink);
}
/* ONE MARK IS A LETTERMARK. Every glyph here draws inside a 24-unit square, so
   a square 22px box is right for all of them but one: GSAP's path measured
   24 x 8.82 units in the browser, which rendered the letters 8px tall and
   unreadable. Its viewBox is cropped to that measured box and it gets its own
   width, so it reads at its own aspect instead of being letterboxed. Cloudflare
   is the next flattest at 24 x 10.85 and needs nothing — a cloud reads at 10px,
   four letters do not. */
.tgrid__mark--lm svg { width: 3rem; height: 1.1rem; }
.tgrid__mono {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 1.75rem; height: 1.75rem; padding: 0 .35rem;
  border: 1px solid var(--hair-bone);
  font-family: var(--mono); font-weight: 500; font-size: .75rem;
  letter-spacing: .01em; color: var(--ink);
}

.tgrid__name {
  margin: 0; font-family: var(--sans); font-weight: 600; font-size: 1rem;
  letter-spacing: -.005em; color: var(--ink);
}
.tgrid__use {
  margin: .35rem 0 0; color: var(--ink-2);
  font-size: .875rem; line-height: 1.55;
}

/* The licence line, under the last group. Mono so it reads as a note about the
   figure above it rather than as more copy. */
.tgrid__legal {
  margin: 1.25rem 0 0; max-width: var(--measure);
  font-family: var(--mono); font-size: .75rem; line-height: 1.6;
  color: var(--ink-2);
}


/* ══ THE DARK BAND, MADE TO READ AS A DECISION ════════════════════════════
   Between two bone bands, S.02 needs an edge or it looks like a rendering
   fault. Same 2px red rule the close already uses, top and bottom.

   The band is full-bleed and carries an inner .rail. It was authored as
   <section class="rail band">, which was fine while the page was ink — but
   with a background on it, .rail's 1136px cap painted a dark rectangle with
   bone margins either side. MEASURED at 1440: section offsetWidth 1136 against
   a 1440 viewport. Fixed in the markup, not with a negative margin. */
.stack-page .band--ink {
  border-top: 2px solid var(--red);
  border-bottom: 2px solid var(--red);
}
.stack-page .band--ink .eyebrow__num { color: var(--red-ink); }


/* ══ THE CLOSE KEEPS ITS OWN COLOUR ═══════════════════════════════════════
   reference.css sets .close { background: var(--plate) } and nothing else —
   the text colour came from body, which used to be --bone. With the body now
   bone-GROUND and ink-TEXT, the whole closing CTA rendered #0a0a0a on #0d0d0d.
   MEASURED before the fix: computed color rgb(10,10,10) on background
   rgb(13,13,13), i.e. the h2, the lede, the mailto and the three facts were
   invisible. Restated here rather than in reference.css, which four other
   pages read. */
.stack-page .close { color: var(--bone); }
.stack-page .close h2, .stack-page .close .lede { color: var(--bone); }
.stack-page .close h2 em { color: var(--bone-2); }
.stack-page .close h3 { color: var(--red-ink); }
.stack-page .close .close__fact p { color: var(--dim-ink); }
.stack-page .close .mailto { color: var(--dim-ink); }
.stack-page .close .mailto a { color: var(--bone); }
.stack-page .close .btn--go { background: var(--bone); color: var(--ink); }
.stack-page .close .btn--ghost { color: var(--bone); border-color: var(--hair-ink); }


/* ══ THE FOOT PULL ════════════════════════════════════════════════════════
   css/chrome.css draws .footpull with linear-gradient(to top,
   rgba(10,10,10,.92), transparent) and already documents what that does to a
   light page: "it darkens the bottom ~46px of the last section". MEASURED here
   at 1440x900 mid-scroll — the scrim washed the bottom row of the platform
   grid grey. chrome.css provides the answer as html.chrome-live
   [data-foot="light"], but declaring it would mean editing the markup inside
   the SVC-CHROME:FOOT markers, which this page does not own. So the same rule
   is declared here instead, page-scoped, using chrome.css's own values.

   THE TRADE, stated rather than hidden: at maximum scroll the bone scrim sits
   over the ink close for ~46px, which reads as the section fading into the
   footer. chrome.css's stated goal is that "the control stays legible on either
   ground", and rgba(10,10,10,.74) on a bone wash clears that on both. A dark
   wash over the white grid at every other scroll position is the worse of the
   two, and it is the one a reader sees constantly.

   NOT A CHROME FIX. Every bone page on the site — /apps, /work/camera — has
   the same fault, and the one-line cure is data-foot="light" in
   partials/chrome.html. See the report. */
html.chrome-live .stack-page .footpull {
  background: linear-gradient(to top, rgba(245, 241, 232, .94), rgba(245, 241, 232, 0));
  color: rgba(10, 10, 10, .74);
}
html.chrome-live .stack-page .footpull__rule { background: rgba(10, 10, 10, .18); }
@media (hover: hover) and (pointer: fine) {
  html.chrome-live .stack-page .footpull:hover { color: var(--ink); }
}
