/* ==========================================================================
   WHO WE REPRESENT — "THE THREE PLATES"   (.trp, index.html § 07)

   Replaces the ruled triptych (css/triptych-plate.css — unlinked, kept on
   disk), which replaced the specimens (css/emblem.css), the brace
   (css/brace.css), the marks (css/marks.css) and the charter
   (css/charter.css). Five attempts at this section now.

   WHY THE RULED TRIPTYCH CAME OUT, AND IT IS THE SAME NOTE THE STANDARD
   GOT: "remove the lines, it makes the design more ugly." That build was
   a plate with a rule over it, a rule under it and two hairlines dividing
   the three panels, and every one of the four ran out from zero width on
   scroll — scaleX on the rules, scaleY on the dividers. Four rules
   filling in sequence is a loading indicator wearing a frame. There is no
   rule anywhere in this file and nothing scales.

   THE READING IS UNCHANGED AND IT IS STILL THE RIGHT ONE: this is the
   section whose subject is other people's property, and three things of
   equal standing want three equal compartments. What changed is what a
   compartment is made of. It was a division of one ruled sheet; it is now
   THREE PLATES — rounded, softly lit, each with its own glow breathing on
   its own clock and its number ghosted through the ground behind the
   mark.

   THE VOCABULARY IS flowstatecreative.org's, TRANSLATED TO GOLD ON STONE
   — the client's own previous project, given as the reference. Measured
   off the live page: radial accent orbs at 6–14% alpha behind the
   section; cards at 12–28px radius on a 2% white fill with a 5% border;
   a wide soft drop, 0 30px 80px; pill CTAs with a gradient-filled
   circular arrow; gradient-clipped display figures. The 32x2 accent bar
   before the section label was already in this system as
   `.eyebrow::before`.

   THE MARKS ARE STILL THE POINT, AND --pk STILL EQUALISES INK AREA, NOT
   HEIGHT: measured at 28,661 / 15,573 / 16,440 opaque pixels over source
   boxes of 480x195 / 480x161 / 480x106, which gives 1 / 1.12 / 0.72.
   Equal heights would set AT&T 39% heavier than Primo. All three are
   reversed to flat white — two of the three source files are dark ink and
   fail against this ground at any opacity, and one monochrome treatment
   is the only one that ranks none of them.

   THE TEXT IS ORGANISED ON TWO EDGES AND NOTHING FLOATS. Every category
   sits on its plate's bottom edge whatever the mark above it measures
   (`grid-template-rows: 1fr auto`), so the three read across on one line.
   The closing sentence used to hang in columns 7–12 under the plate,
   half a container wide with nothing beside it; it is now inside a
   full-width panel that reaches both container edges.

   THE SECTION IS ALIVE AT REST. Five clocks, all long, all out of phase,
   not one of them travelling toward a full state:

     orb A     30s   drifts and swells behind the head
     orb B     38s   the same, out of phase, behind the plates
     glow x3   16s   each plate's own light, staggered 4s apart by --trpi
                     so the three are never in step

   NOTHING SWEEPS, FILLS, COUNTS OR RUNS OUT. Standing constraint on this
   page: three times now a scrubbed element that travelled toward a full
   state has been read as a loading bar.

   REST IS THE FINISHED SECTION. --trpp initial-values at 1, so with no
   JS, a dead CDN or reduced motion all three plates are at full key.

   NAME CHECK: `.trp__card`, `.trp__orb`, `.trp__glow`, `.trp__ghost`,
   `.trp__arrow`, `--trpi` and `--trpr` were grepped across css/, js/ and
   every *.html before a line was written. Zero hits.
   ========================================================================== */

/* the section's scrub clock. 1 = all three plates at full key. */
@property --trpp { syntax: "<number>"; inherits: true; initial-value: 1; }
/* THE HAND ON ONE PLATE. 0 shut, 1 open, TRANSITIONED ON THE CARD so the
   mark's key, the ghost's retreat and the entry's arrival are one clock
   rather than three that can drift apart. Initial-value 1 is deliberate and
   is the whole no-JS/touch/reduced-motion contract in one line: the plate's
   resting state IS OPEN, and only a device that can actually hover is ever
   told to shut it. Nothing can hide this copy by failing. */
@property --trph { syntax: "<number>"; inherits: true; initial-value: 1; }

.trp {
  position: relative;
  padding-block: clamp(2.4rem, 1.7rem + 3.2vw, 5rem);
  /* the orbs hang off both edges; nothing may push the document sideways.
     Vertical is left alone so the plates' shadows can fall into the
     section's own padding. */
  overflow-x: clip;

  /* THE LOCAL ROUNDING, declared once and shared with the standard
     (--asyr in css/assay.css) so the two premium sections agree.
     --radius-md is 3px and is the site's editorial scale; it is
     deliberately not used here. */
  --trpr: clamp(0.9rem, 0.6rem + 0.9vw, 1.4rem);

  /* --------------------------------------------------------------------
     TWO CURVES, AND THE PLATE OPENS ON ONE AND SHUTS ON THE OTHER.

     A hover that plays the same duration and the same easing in both
     directions is the single thing that makes an interaction feel built
     rather than designed. Nothing physical behaves that way: a thing that
     is set in motion arrives slowly and leaves quickly, and every
     interface that reads as expensive is asymmetric about it.

     --trp-in is an exponential-out. It covers most of its distance early
     and then takes a long, flat tail to settle, which is what reads as
     WEIGHT - the plate looks like it is coming to rest rather than
     stopping. It is deliberately slower than the site's --ease-out
     (0.22, 1, 0.36, 1), which is tuned for the scroll entrances and is
     too eager for something a reader is holding still to look at.

     --trp-out is nearly the same curve run the other way and over two
     thirds of the time. Leaving is not a thing anyone is watching; a slow
     exit just delays the next plate, and three slow exits in a row while
     a reader moves along the set is what makes a section feel sticky.
     -------------------------------------------------------------------- */
  --trp-in: cubic-bezier(0.16, 1, 0.3, 1);
  --trp-out: cubic-bezier(0.4, 0, 0.65, 1);
}

/* --------------------------------------------------------------------------
   THE GROUND. Two gold orbs well under the ink, on long clocks out of
   phase with each other.
   -------------------------------------------------------------------------- */
.trp__orb {
  position: absolute;
  z-index: 0;
  border-radius: 50%;
  pointer-events: none;
  will-change: transform, opacity;
}

.trp__orb--a {
  width: clamp(19rem, 32vw, 36rem);
  aspect-ratio: 1;
  top: -12%;
  right: -9%;
  background: radial-gradient(circle, rgb(184 145 88 / 0.12) 0%, rgb(184 145 88 / 0) 68%);
  animation: trp-drift-a 30s ease-in-out infinite alternate;
}

.trp__orb--b {
  width: clamp(16rem, 26vw, 29rem);
  aspect-ratio: 1;
  left: -11%;
  bottom: -16%;
  background: radial-gradient(circle, rgb(143 109 56 / 0.13) 0%, rgb(143 109 56 / 0) 70%);
  animation: trp-drift-b 38s ease-in-out infinite alternate;
}

@keyframes trp-drift-a {
  from { transform: translate3d(0, 0, 0) scale(1); opacity: 0.72; }
  to   { transform: translate3d(-4%, 5%, 0) scale(1.1); opacity: 1; }
}
@keyframes trp-drift-b {
  from { transform: translate3d(0, 0, 0) scale(1.09); opacity: 1; }
  to   { transform: translate3d(4.5%, -4%, 0) scale(1); opacity: 0.68; }
}

/* --------------------------------------------------------------------------
   THE HEAD — the claim left, the one link right, on one baseline.
   -------------------------------------------------------------------------- */
.trp__head {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  column-gap: clamp(1.5rem, 1rem + 2.4vw, 3.5rem);
  align-items: end;
  margin-bottom: clamp(1.8rem, 1.3rem + 2.4vw, 3.4rem);
}

/* the head's first column. min-width: 0 and nothing else: an auto-sized
   grid track refuses to shrink below its longest unbreakable content, and
   the pill in the second column would otherwise be pushed off the
   container's right edge at narrow widths. */
.trp__lede { min-width: 0; }

.trp__h {
  margin: 0;
  font-size: clamp(1.75rem, 1.3rem + 2vw, 2.9rem);
  font-weight: 600;
  letter-spacing: -0.035em;
  line-height: 1.06;
  text-wrap: balance;
  max-width: 17ch;
}

/* the metallic phrase. Static gradient, breath on brightness: a gradient
   that slides its own background-position is a highlight travelling
   across a word, and travelling highlights are what this page has
   repeatedly been told to stop doing. */
.trp__h em {
  font-style: italic;
  font-weight: 500;
  background: linear-gradient(104deg,
    var(--gold-light) 0%,
    var(--gold) 46%,
    var(--gold-shadow) 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
  animation: trp-sheen 8s ease-in-out infinite alternate;
}

@keyframes trp-sheen {
  from { filter: brightness(0.94); }
  to   { filter: brightness(1.12); }
}

/* THE PILL. The reference's CTA: a rounded outline with a gradient-filled
   circular arrow on the end. It replaces a plain underlined text link,
   which was the one element in the head with no weight at all. */
.trp__on {
  display: inline-flex;
  align-items: center;
  gap: 0.7rem;
  padding: 0.45rem 0.45rem 0.45rem 1.1rem;
  border-radius: 50px;
  border: 1px solid rgb(184 145 88 / 0.28);
  background: rgb(184 145 88 / 0.07);
  color: var(--ink);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  text-decoration: none;
  white-space: nowrap;
  transition: border-color 0.45s var(--ease-out), background-color 0.45s var(--ease-out),
              color 0.45s var(--ease-out);
}

.trp__arrow {
  display: grid;
  place-items: center;
  width: 2rem;
  aspect-ratio: 1;
  border-radius: 50%;
  background: linear-gradient(135deg, var(--gold-light), var(--gold-shadow));
  color: var(--obsidian);
  transition: transform 0.45s var(--ease-out);
}

/* --------------------------------------------------------------------------
   THE THREE PLATES
   -------------------------------------------------------------------------- */
.trp__set {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(0.85rem, 0.6rem + 1vw, 1.5rem);
  margin: 0;
  padding: 0;
  list-style: none;
}

.trp__card {
  --s: calc(0.08 + var(--trpi) * 0.13);
  --lp: clamp(0, calc((var(--trpp) - var(--s)) * 3), 1);
  position: relative;
  z-index: 0;
  display: grid;
  /* THE CATEGORY SITS ON THE PLATE'S BOTTOM EDGE whatever the mark above
     it measures, so the three read across on one line. The marks are
     53px, 59px and 38px tall — anything that let them push the category
     would put the three words on three different baselines. */
  grid-template-rows: 1fr auto;
  /* SIZED FOR THE OPEN ENTRY, NOT THE SHUT ONE, and that is the only way a
     row of three can open without moving the page. A plate that grew to fit
     the sentence would push its own neighbours' baselines and shove
     everything below it down the document on a mouse move. So the tallest
     state is what the box is cut to, and the shut state simply carries the
     difference as air above the mark - which is also what stops three logos
     in three boxes reading as a banner ad.

     ONE FLAT NUMBER AND NOT A clamp() ON vw, WHICH IS THE OPPOSITE OF WHAT
     THIS BOX WANTS AND TOOK THREE MEASUREMENTS TO SEE. A viewport-scaled
     min-height gets SMALLER as the window narrows; the entry inside it gets
     TALLER, because a narrower column wraps the same sentence onto more
     lines. Measured, three across: 1440 -> 411px wide, entry 259 tall. 1280
     -> 382 / 275. 1024 -> 298 / 256. 900 -> 260 / 267. The two curves cross,
     so any vw expression that fits at one end overflows at the other, and a
     clamp tuned at 1280 clipped the last line at 1024 by 2px and at 900 by
     58 - exactly the kind of fault that fits on the machine it was tuned on
     and is found by a stranger on a laptop.

     18rem covers all four, with the tightest slack at 1280 (13px). It is also
     BELOW the 19.5rem this replaces everywhere the two overlap: 288 against
     312 at 1440. The plate got shorter and started carrying a sentence in the
     same pass, which is the point - the old box was 312px tall to hold a logo
     and one word, and that is what made it read as oversized. */
  min-height: 18rem;
  padding: clamp(1.15rem, 0.85rem + 1.15vw, 1.85rem);
  border-radius: var(--trpr);
  border: 1px solid rgb(184 145 88 / 0.13);
  background: linear-gradient(168deg,
    rgb(234 230 223 / 0.038) 0%,
    rgb(234 230 223 / 0.01) 46%,
    rgb(234 230 223 / 0) 100%);
  box-shadow:
    0 24px 60px -34px rgb(0 0 0 / 0.6),
    inset 0 1px 0 rgb(255 255 255 / 0.04);
  overflow: hidden;
  /* the entrance: a few pixels of rise, staggered across the three */
  transform: translate3d(0, calc((1 - var(--lp)) * 16px), 0);
  opacity: calc(0.08 + var(--lp) * 0.92);
  /* THE LEAVING LIST. The arriving one is on the :hover rule, which is the
     only way CSS lets a transition differ by direction. */
  transition: transform 0.46s var(--trp-out), border-color 0.4s var(--trp-out),
              box-shadow 0.46s var(--trp-out), --trph 0.5s var(--trp-out);
  outline-offset: -4px;
}

/* the plate is focusable now, so the ring has to be real. Outside the hover
   query on purpose: a keyboard is not a mouse and a touch screen can have
   one. */
.trp__card:focus-visible {
  outline: 2px solid var(--gold-light);
}
.trp__card:nth-child(1) { --trpi: 0; }
.trp__card:nth-child(2) { --trpi: 1; }
.trp__card:nth-child(3) { --trpi: 2; }

/* EACH PLATE'S OWN LIGHT, on its own clock. The delay is derived from the
   plate's index, so the three are never in step and the row never pulses
   as one object — which is what would make it read as a mechanism rather
   than as light. */
.trp__glow {
  position: absolute;
  z-index: 0;
  top: -34%;
  left: -18%;
  width: 78%;
  aspect-ratio: 1;
  border-radius: 50%;
  pointer-events: none;
  background: radial-gradient(circle, rgb(184 145 88 / 0.17) 0%, rgb(184 145 88 / 0) 68%);
  animation: trp-breathe 16s ease-in-out infinite alternate;
  animation-delay: calc(var(--trpi) * -4s);
  transition: scale 0.55s var(--trp-out), filter 0.55s var(--trp-out);
}

@keyframes trp-breathe {
  from { transform: scale(0.9); opacity: 0.55; }
  to   { transform: scale(1.12); opacity: 1; }
}

/* THE GHOSTED FIGURE. The plate's number, set at display size and run off
   the bottom-right corner so the plate is cropping it — the move that
   gives a card depth without giving it another object. Gradient-clipped
   so it fades as it descends, and it is the only place the numeral
   appears: a small folio AND a ghosted one is the same number twice. */
.trp__ghost {
  position: absolute;
  z-index: 0;
  right: -0.04em;
  bottom: -0.3em;
  font-size: clamp(4.5rem, 2.6rem + 5.4vw, 8.5rem);
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.05em;
  font-variant-numeric: tabular-nums lining-nums;
  pointer-events: none;
  background: linear-gradient(180deg,
    rgb(184 145 88 / 0.22) 0%,
    rgb(184 145 88 / 0.04) 72%,
    rgb(184 145 88 / 0) 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
  transform-origin: 100% 100%;
  /* AND IT GETS OUT OF THE WAY WHEN THE ENTRY OPENS. The numeral lives in the
     bottom-right corner, which is exactly where the sentence lands, and a
     100px figure behind two lines of 14px type is not depth, it is a legibility
     problem. Shut, the plate is a numbered index and the figure is the loudest
     thing on it; open, the reader is reading, so it recedes.

     BOTH VALUES ARE ARITHMETIC ON --trph AND NEITHER HAS A TRANSITION OF ITS
     OWN. --trph is already interpolating on the card, so the figure cannot
     drift out of step with the row that displaced it - which it would the
     moment the two carried separate durations and somebody tuned one. The
     `transition: filter` that used to be here went with the brightness bump
     it served. */
  opacity: calc(1 - var(--trph) * 0.72);
  scale: calc(1 - var(--trph) * 0.05);
}

/* the mark, at the size a client's property should be shown at */
.trp__mark {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  align-self: center;
  justify-self: start;
  --trpu: clamp(32px, 1.25rem + 2.15vw, 50px);
  height: calc(var(--trpu) * 1.12);
  /* IT TRAVELS BECAUSE THE ROW SHRANK; IT SETTLES BECAUSE OF THIS. 5% is
     nothing on its own and everything next to the 50px of travel the grid
     hands it: without it the mark arrives at the top of the plate at exactly
     the size it left, which reads as a thing that slid. With it, the mark
     stops being the subject of the plate and becomes its letterhead.
     transform-origin at the left edge because the mark is justify-self:start
     and the entry below it is flush left - shrinking about the centre would
     walk it off that line and back again on every hover.
     No transition: --trph is already interpolating on the card, so this is in
     step with the row by construction rather than by two matching numbers. */
  transform-origin: 0 50%;
  scale: calc(1 - var(--trph) * 0.05);
}

.trp__mark img {
  display: block;
  height: calc(var(--trpu) * var(--pk, 1));
  width: auto;
  max-width: 100%;
  object-fit: contain;
  filter: brightness(0) invert(1);
  opacity: 0.78;
  transition: opacity 0.5s var(--ease-out);
}

/* --------------------------------------------------------------------------
   THE ENTRY. The category is the index line and never moves or changes; what
   opens is everything under it.

   0fr TO 1fr IS THE WHOLE REVEAL. A collapsed grid row interpolates to the
   content's OWN height, so nothing here has a hard-coded number in it and
   the three sentences - which wrap to two lines or three depending on the
   viewport - each open to exactly their own size. The alternative, a fixed
   height or a max-height guess, is the thing that clips the last line of one
   card at one width and nobody notices for a month.

   .trp__inner CARRIES min-height: 0 BECAUSE A GRID ITEM WILL NOT GO BELOW ITS
   CONTENT unless it is told to. Without it the row cannot reach 0fr, the
   plate ships open on every device and the entire effect silently does not
   happen.
   -------------------------------------------------------------------------- */
.trp__entry {
  position: relative;
  z-index: 1;
  min-width: 0;
}

.trp__detail {
  display: grid;
  grid-template-rows: 1fr;
  overflow: hidden;
  transition: grid-template-rows 0.5s var(--trp-out) 0.06s;
}

/* min-height: 0 AND NOTHING ELSE. The copy used to fade as one block from
   here, on the same clock as the row, and that is what made the whole move
   read as a drawer: the container opened and its contents appeared at the
   same instant and the same rate, which is not how anything is uncovered.
   The three lines below now each arrive on their own beat inside the opening
   row, so the row opens FIRST and the entry is written into it. */
.trp__inner { min-height: 0; }

/* THE HAIRLINE FADES IN AT FULL WIDTH AND DOES NOT DRAW ITSELF, which is a
   standing constraint on this section and not a preference: the build this
   replaced was struck for exactly that - "four rules filling in sequence is a
   loading indicator wearing a frame". One rule, arriving whole, is a rule.
   The same rule growing from zero is a meter. */
.trp__hair {
  display: block;
  height: 1px;
  margin-top: clamp(0.55rem, 0.45rem + 0.35vw, 0.8rem);
  background: linear-gradient(90deg,
    rgb(184 145 88 / 0.42) 0%,
    rgb(184 145 88 / 0.16) 58%,
    rgb(184 145 88 / 0) 100%);
  /* OPACITY ONLY, NO TRAVEL. It is one pixel tall: a hairline that also rises
     9px is a hairline sliding across the plate, and the eye reads the slide
     instead of the line. The two things under it travel; this one arrives. */
  transition: opacity 0.2s var(--trp-out);
}

/* the two lines that do travel. Same 9px, same curve, 80ms apart - close
   enough to read as one gesture, far enough that the sentence lands before
   its terms do. */
.trp__text,
.trp__qual {
  transition: opacity 0.2s var(--trp-out), transform 0.2s var(--trp-out);
}

.trp__text {
  margin: clamp(0.55rem, 0.45rem + 0.35vw, 0.8rem) 0 0;
  font-size: clamp(0.85rem, 0.8rem + 0.2vw, 0.95rem);
  line-height: 1.5;
  color: var(--vein);
  text-wrap: pretty;
}

/* the terms, and the only bold in the plate: it is the two or three words a
   reader would repeat back, so it is the two or three words set to be read
   first. */
.trp__qual {
  margin: clamp(0.4rem, 0.34rem + 0.26vw, 0.6rem) 0 0;
  font-size: clamp(0.78rem, 0.74rem + 0.16vw, 0.85rem);
  line-height: 1.4;
  color: rgb(234 230 223 / 0.5);
}

.trp__qual b {
  font-weight: 600;
  color: var(--gold-light);
}

.trp__cat {
  position: relative;
  z-index: 1;
  margin: clamp(0.75rem, 0.55rem + 0.7vw, 1.1rem) 0 0;
  font-size: clamp(1.02rem, 0.9rem + 0.55vw, 1.32rem);
  font-weight: 600;
  letter-spacing: -0.024em;
  line-height: 1.18;
  color: var(--ink);
  text-wrap: balance;
  transition: color 0.5s var(--ease-out);
}

/* --------------------------------------------------------------------------
   THE CLOSE — what the three amount to, in a panel that reaches both
   container edges. It used to hang in columns 7–12 with nothing beside
   it, which is the dead-channel fault this brief keeps calling out.
   -------------------------------------------------------------------------- */
.trp__close {
  position: relative;
  z-index: 1;
  margin-top: clamp(0.85rem, 0.6rem + 1vw, 1.5rem);
  padding: clamp(1.1rem, 0.85rem + 1vw, 1.7rem) clamp(1.3rem, 1rem + 1.3vw, 2.1rem);
  border-radius: var(--trpr);
  border: 1px solid rgb(184 145 88 / 0.1);
  background: linear-gradient(100deg,
    rgb(184 145 88 / 0.062) 0%,
    rgb(234 230 223 / 0.014) 46%,
    rgb(234 230 223 / 0) 100%);
  /* the panel arrives last, but not THAT last: at 0.6/3.2 it was still at
     0.32 while all three plates were already at full key, which reads as
     a piece that failed to load rather than as a piece that follows. */
  opacity: clamp(0.24, calc((var(--trpp) - 0.46) * 2.4), 1);
}

.trp__say {
  margin: 0;
  max-width: 62ch;
  font-size: clamp(1rem, 0.92rem + 0.5vw, 1.3rem);
  font-weight: 500;
  letter-spacing: -0.02em;
  line-height: 1.44;
  color: var(--ink);
  text-wrap: pretty;
}

/* --------------------------------------------------------------------------
   THE HAND
   -------------------------------------------------------------------------- */
@media (hover: hover) and (pointer: fine) {
  /* THE ONLY PLACE THE ENTRY IS EVER SHUT. Everything above ships open; a
     device that can hover is the only one that can be given something back,
     so it is the only one that has anything taken away. A phone, a keyboard
     with no pointer, a browser with no :hover support and anyone on reduced
     motion all read three finished plates. */
  .trp__card { --trph: 0; }
  .trp__detail { grid-template-rows: 0fr; }
  .trp__hair { opacity: 0; }
  .trp__text,
  .trp__qual { opacity: 0; transform: translate3d(0, 9px, 0); }

  /* ------------------------------------------------------------------
     THE ORDER THINGS HAPPEN IN, WHICH IS THE WHOLE DIFFERENCE BETWEEN
     THIS AND A CARD THAT REVEALS SOME TEXT.

     Everything used to run on one 0.62s clock: the plate lifted, the row
     opened and every word appeared, together, at one rate. That is
     legible and it is completely inert - four things moving in perfect
     unison read as one thing being switched on.

       0ms     the plate answers. Border and lift, 0.4s, so the pointer
               gets its acknowledgement in the first frames and never
               waits on the content.
       0ms     the row starts opening, 0.68s. The mark rides it up.
       110ms   the hairline arrives - the entry's top edge, so it is
               drawn before anything is written under it.
       180ms   the sentence.
       260ms   the terms.

     BY 180ms THE ROW IS ALREADY 70% OPEN, because --trp-in front-loads
     its distance. So the copy is never writing into a space that has not
     been made for it, and the last line lands at 810ms against the row's
     680ms - the entry finishes just after the box it lives in, which is
     the beat that makes it feel finished rather than cut off.
     ------------------------------------------------------------------ */
  .trp__card:hover,
  .trp__card:focus-visible {
    --trph: 1;
    transform: translate3d(0, -7px, 0);
    border-color: rgb(184 145 88 / 0.42);
    box-shadow:
      0 34px 70px -30px rgb(0 0 0 / 0.72),
      0 0 44px -18px rgb(184 145 88 / 0.45),
      inset 0 1px 0 rgb(255 255 255 / 0.07);
    transition: transform 0.4s var(--trp-in), border-color 0.34s var(--trp-in),
                box-shadow 0.6s var(--trp-in), --trph 0.68s var(--trp-in);
  }

  .trp__card:hover .trp__detail,
  .trp__card:focus-visible .trp__detail {
    grid-template-rows: 1fr;
    transition: grid-template-rows 0.68s var(--trp-in);
  }

  .trp__card:hover .trp__hair,
  .trp__card:focus-visible .trp__hair {
    opacity: 1;
    transition: opacity 0.42s var(--trp-in) 0.11s;
  }
  .trp__card:hover .trp__text,
  .trp__card:focus-visible .trp__text {
    opacity: 1;
    transform: none;
    transition: opacity 0.55s var(--trp-in) 0.18s, transform 0.55s var(--trp-in) 0.18s;
  }
  .trp__card:hover .trp__qual,
  .trp__card:focus-visible .trp__qual {
    opacity: 1;
    transform: none;
    transition: opacity 0.55s var(--trp-in) 0.26s, transform 0.55s var(--trp-in) 0.26s;
  }

  .trp__card:hover .trp__mark img,
  .trp__card:focus-visible .trp__mark img { opacity: 1; }
  .trp__card:hover .trp__cat,
  .trp__card:focus-visible .trp__cat { color: var(--white); }

  /* the plate's own light comes up with the entry, and takes the longest of
     anything here to do it - 0.9s against the row's 0.68. A light that
     arrives at the same speed as the thing it is lighting reads as a state
     change; one that is still blooming after everything else has settled
     reads as a light. `scale` and `filter`, because the 16s breathe owns
     `transform` and `opacity` — the two-property split this file already
     uses on the orbs. */
  .trp__card:hover .trp__glow,
  .trp__card:focus-visible .trp__glow {
    scale: 1.1;
    filter: brightness(1.45);
    transition: scale 0.9s var(--trp-in), filter 0.9s var(--trp-in);
  }

  /* the other two step back so the one being looked at is the only mark
     at full key. Marks only — the category stays legible, because copy
     that greys out as the mouse moves punishes reading. */
  .trp__set:hover .trp__card:not(:hover) .trp__mark img { opacity: 0.42; }

  .trp__on:hover {
    border-color: rgb(192 156 96 / 0.6);
    background: rgb(184 145 88 / 0.14);
    color: var(--white);
  }
  .trp__on:hover .trp__arrow { transform: translateX(3px); }
}

/* --------------------------------------------------------------------------
   NARROW, AND THE SWITCH MOVED FROM 720 TO 940 BECAUSE THE PLATE'S JOB
   CHANGED. The old note read "three across holds a long way down, because a
   plate only has to carry a mark and one or two words" - and that was true of
   a plate that carried a mark and one or two words. It now carries a
   sentence, and a third of a 900px container is 260px: AT&T's line breaks
   four ways in a column that narrow, which is not a paragraph, it is a
   column of two-word rows.

   940 is where a third of the container stops being able to hold the copy at
   a sensible measure. Below it the three stack and each plate turns on its
   side - mark left, entry right - which gives every sentence the full
   container width and takes the line counts back down to two.
   -------------------------------------------------------------------------- */
@media (max-width: 900px) {
  .trp__head {
    grid-template-columns: minmax(0, 1fr);
    row-gap: clamp(1.1rem, 0.9rem + 1vw, 1.6rem);
    align-items: start;
  }
  .trp__on { justify-self: start; }
  .trp__h { max-width: 22ch; }
  /* NO min-height HERE ANY MORE. The plates are already on their side by this
     width (see the 940 block below) where the box is whatever its content
     measures, and a height re-imposed here would land after that rule in the
     cascade and put the reserved air back on a plate that has nothing to
     reserve it for. */
}

@media (max-width: 940px) {
  .trp__set { grid-template-columns: minmax(0, 1fr); }
  .trp__card {
    grid-template-rows: auto;
    grid-template-columns: minmax(0, auto) minmax(0, 1fr);
    align-items: center;
    column-gap: clamp(1rem, 0.7rem + 1.4vw, 1.6rem);
    min-height: 0;
    padding-block: clamp(1.15rem, 0.9rem + 1vw, 1.5rem);
  }
  /* ON ITS SIDE THE PLATE IS ALREADY OPEN AND MUST STAY THAT WAY. min-height
     is 0 here, so the box is whatever its content measures - there is no
     reserved air for an entry to expand into, and a plate that grew on tap
     would shove the two below it. This is also a touch layout, so the hover
     query never runs and --trph is 1 regardless; the row is set to 1fr
     explicitly anyway, so a hybrid laptop with a touchscreen AND a mouse
     cannot shut a plate that has nowhere to reopen into. */
  .trp__detail { grid-template-rows: 1fr; }
  .trp__card { --trph: 1; }
  /* --trph IS 1 HERE, WHICH WOULD ALSO HOLD THE MARK AT ITS LETTERHEAD SIZE
     FOREVER. It shrinks 5% up there because it is giving the row its space
     back as the entry opens into it; side-on there is no row to give
     anything to and no open state to be in, so the client's mark would just
     be permanently 5% small on every phone for a reason that does not exist
     at this width. The ghost's retreat is NOT undone with it: that one is
     about the sentence being readable over the figure, and the sentence is
     on screen here. */
  .trp__mark { scale: 1; }
  .trp__cat { margin: 0; }
  .trp__ghost { font-size: 4.6rem; bottom: -0.34em; }
  .trp__glow { top: -60%; width: 46%; }
}

@media (max-width: 460px) {
  .trp__card {
    grid-template-columns: minmax(0, 1fr);
    row-gap: 0.85rem;
    align-items: start;
  }
  .trp__mark { justify-self: start; }
}

/* --------------------------------------------------------------------------
   REDUCED MOTION. Every clock stops. The section is a finished
   composition without any of them.
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .trp__orb,
  .trp__glow,
  .trp__h em { animation: none; }
  .trp__card,
  .trp__mark,
  .trp__mark img,
  .trp__cat,
  .trp__ghost,
  .trp__detail,
  .trp__hair,
  .trp__text,
  .trp__qual,
  .trp__glow,
  .trp__on,
  .trp__arrow { transition: none; }

  /* AND THE ENTRY IS SIMPLY OPEN. Reduced motion and a mouse can be the same
     visitor, so the hover query above still applies to them and would leave
     the sentence behind a gesture with the animation that justified it
     switched off - copy hidden for no reason at all. This block sits last in
     the file and matches at the same specificity, so it wins on source order
     and every plate is a finished, readable entry.

     The :hover rules are more specific and still fire; they have nothing left
     to open, which is correct. The lift and the border stay: those are
     feedback that the pointer is on something, not motion for its own sake,
     and with the transitions off they are instant. */
  .trp__card { --trph: 1; }
  .trp__detail { grid-template-rows: 1fr; }
  .trp__ghost { opacity: 0.28; scale: 1; }
  .trp__mark { scale: 1; }
  /* the staged arrival is the part that cannot survive this setting, so the
     three lines are simply present. Written flat rather than left to the
     hover rules, which are more specific and would otherwise re-hide them
     the moment the pointer left a plate. */
  .trp__hair,
  .trp__text,
  .trp__qual { opacity: 1; transform: none; }
}
