/* ==========================================================================
   FRONTLINE21 — COMPONENTS
   Actions, media plates, the shield formation, forms, reveal states.
   ========================================================================== */

/* --- Actions ---------------------------------------------------------------
   Square corners, hairline borders, no pills, no glass, no shadow. */

.actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}

.btn {
  --btn-fg: var(--paper);
  --btn-bg: transparent;
  --btn-bd: var(--paper-faint);
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 12px;
  padding: 15px 20px 13px;
  border: 1px solid var(--btn-bd);
  background: var(--btn-bg);
  color: var(--btn-fg);
  font-family: var(--font-display);
  font-size: var(--t-micro);
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  line-height: 1;
  transition: color var(--dur-fast) var(--ease-out),
    background-color var(--dur-fast) var(--ease-out),
    border-color var(--dur-fast) var(--ease-out);
}

.btn::after {
  content: '';
  width: 14px;
  height: 1px;
  background: currentColor;
  flex: none;
  transition: width var(--dur-mid) var(--ease-out);
}

.btn:hover::after,
.btn:focus-visible::after {
  width: 22px;
}

/* The acquisition button. White on Frontline red from 8 September: it was
   white on charcoal, which read as the same weight as Look inside beside it,
   and the one red thing on a near-black page is the thing to press.

   The label is centred and carries a rule of the same length on both sides.
   The single trailing rule that .btn draws is the house's dash; a second one
   ahead of the label makes the pair the brief asks for, and because both are
   drawn boxes rather than typed characters they are decoration a screen
   reader cannot read out. The accessible name stays Get the Field Manual.

   The rules shorten with the type on a narrow phone rather than pushing the
   label into two lines, and disappear under 340px, where the label needs the
   whole width. */
.btn--primary {
  --btn-fg: var(--paper);
  --btn-bg: var(--f21-red);
  --btn-bd: var(--f21-red);
  justify-content: center;
  gap: clamp(10px, 3vw, 16px);
  padding-inline: clamp(16px, 5vw, 28px);
  letter-spacing: clamp(0.1em, 0.5vw, 0.16em);
}

.btn--primary::before {
  content: '';
  width: 14px;
  height: 1px;
  background: currentColor;
  flex: none;
  transition: width var(--dur-mid) var(--ease-out);
}

.btn--primary:hover::before,
.btn--primary:focus-visible::before {
  width: 22px;
}

@media (max-width: 339px) {
  .btn--primary::before,
  .btn--primary::after { display: none; }
}

.btn--primary:hover,
.btn--primary:focus-visible {
  --btn-fg: var(--f21-red);
  --btn-bg: var(--paper);
  --btn-bd: var(--paper);
}

.btn--ghost:hover,
.btn--ghost:focus-visible {
  --btn-bd: var(--paper);
}

.btn--sm {
  padding: 11px 14px 9px;
  font-size: 10px;
  letter-spacing: 0.18em;
}

/* --- Media plates ----------------------------------------------------------
   Every plate holds its own space, states what belongs in it, and is marked
   for replacement. No invented photography, no fake people, no stock energy. */

.plate {
  position: relative;
  overflow: hidden;
  background-color: var(--ink-raised);
  background-image: url('../images/texture/carbon-plate-512.png');
  background-size: 380px;
  border: 1px solid var(--ink-line);
  isolation: isolate;
}

.plate::before {
  content: '';
  position: absolute;
  inset: 0;
  background: radial-gradient(
    120% 90% at 50% 40%,
    rgba(244, 245, 244, 0.05),
    rgba(12, 15, 15, 0.68) 78%
  );
  z-index: 0;
}

/* A declared empty frame, drawn the way a spec draws one: corner to corner
   hairlines and a centre registration mark. It reads as an art directed plate
   awaiting its media, not as a broken image. */
.plate::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  opacity: 0.75;
  background-repeat: no-repeat;
  background-position: 0 0, 0 0, center, center;
  background-size: 100% 100%, 100% 100%, 26px 1px, 1px 26px;
  background-image:
    linear-gradient(
      to bottom right,
      transparent calc(50% - 0.5px),
      var(--ink-line) calc(50% - 0.5px),
      var(--ink-line) calc(50% + 0.5px),
      transparent calc(50% + 0.5px)
    ),
    linear-gradient(
      to top right,
      transparent calc(50% - 0.5px),
      var(--ink-line) calc(50% - 0.5px),
      var(--ink-line) calc(50% + 0.5px),
      transparent calc(50% + 0.5px)
    ),
    linear-gradient(var(--paper-faint), var(--paper-faint)),
    linear-gradient(var(--paper-faint), var(--paper-faint));
}

.plate__marks {
  position: absolute;
  inset: 12px;
  z-index: 2;
  pointer-events: none;
}

.plate__marks::before,
.plate__marks::after {
  content: '';
  position: absolute;
  width: 16px;
  height: 16px;
  border-color: var(--f21-red);
  border-style: solid;
}

.plate__marks::before {
  top: 0;
  left: 0;
  border-width: 1px 0 0 1px;
}

.plate__marks::after {
  bottom: 0;
  right: 0;
  border-width: 0 1px 1px 0;
}

.plate__meta {
  position: absolute;
  inset: 24px;
  z-index: 3;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 12px;
}

.plate__row {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
}

.plate__brief {
  font-family: var(--font-text);
  font-size: var(--t-small);
  line-height: 1.4;
  color: var(--paper-dim);
  max-width: 42ch;
  text-transform: none;
  letter-spacing: 0;
}

.plate--16x9 { aspect-ratio: 16 / 9; }
.plate--21x9 { aspect-ratio: 21 / 9; }
.plate--4x3  { aspect-ratio: 4 / 3; }
.plate--3x4  { aspect-ratio: 3 / 4; }
.plate--1x1  { aspect-ratio: 1 / 1; }

/* Mobile art direction: wide plates are recomposed, not letterboxed. */
@media (max-width: 720px) {
  .plate--21x9,
  .plate--16x9 { aspect-ratio: 4 / 5; }
  .plate--3x4  { aspect-ratio: 4 / 3; }

  .plate__meta { inset: 18px; }
  .plate__brief { font-size: 13px; }
}

/* --- The Phalanx ---------------------------------------------------------------
   The authentic Frontline21 lockup, working. Two poses and only two:

     phalanx    the compact mark: wordmark, five shields shoulder to shoulder
                beneath it in the chevron the artwork sets
     deployed   the five shields in rank across the formation, each one a
                control, names beneath, the line under them

   fs60p.js sets data-fs60p on the formation from where the movement is and
   writes the compact pose as per shield transforms measured from the deployed
   layout, so nothing here animates a layout property. The stylesheet default is
   deployed, which is what a reader with scripts off, or with reduced motion,
   gets: five real buttons where a hand can reach them. */

/* THE FORMATION, 7 September. A centre with four companions on the diagonals,
   which is the arrangement of the lockup itself and the one the breakup
   behaviour was built to resolve into. The rank of five across a whole screen
   was the layout problem: it could not stand beside anything.

   The positions are the authored ones and they do not move when the active
   discipline changes: 1 northwest, 2 northeast, 3 the centre, 4 southwest,
   5 southeast, which is Servant Leadership, Self-Control, Moral Courage,
   Brotherhood and Stewardship. That is the historical mapping, recovered from
   the lockup's own left to right order, and it is also the one the brief
   names.

   fs60p.js measures the compact pose from wherever the stylesheet puts each
   control, so changing the deployed arrangement here needs no change there:
   the mark still breaks into exactly these five positions. */

.phalanx {
  --ph-shield-w: clamp(48px, 4.4vw, 78px);
  --ph-lead-w: calc(var(--ph-shield-w) * 1.2);
  --ph-tall: calc(var(--ph-shield-w) * 1.1464); /* 88.383 / 77.098 */
  --ph-mark-w: min(100%, calc(var(--ph-shield-w) * 5.4));
  position: relative;
  display: grid;
  justify-items: center;
  align-content: center;
  row-gap: clamp(10px, 1.2vw, 18px);
}

/* The whole mark, behind the formation rather than above it. It is the pose
   the shields fold back into, not a second logo taking a band of its own, so
   it is taken out of flow: the formation's height is the five controls. */
.phalanx__mark {
  position: absolute;
  top: 50%;
  left: 50%;
  width: var(--ph-mark-w);
  transform: translate(-50%, -50%);
  transition: opacity 620ms var(--ease-out);
  color: var(--paper);
  pointer-events: none;
}

.phalanx__wordmark {
  display: block;
  width: 100%;
  height: auto;
}

/* Three columns and two rows, with the centre spanning both and standing in
   the middle of them. A third row for the centre alone would push the four
   companions a hundred pixels apart and stop reading as a formation; spanning
   is what makes the cluster a diamond rather than a column of ranks, and it
   is what lets the whole thing sit beside the discipline on a desktop and
   above it on a phone. */
.phalanx__rank {
  width: 100%;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  grid-template-rows: auto auto;
  column-gap: clamp(6px, 0.9vw, 16px);
  row-gap: clamp(6px, 0.9vw, 14px);
  justify-items: center;
  align-items: start;
  /* Auto rows in a grid stretch to fill spare height by default, which would
     pull the three ranks of the formation apart whenever the discipline
     beside it is the taller column. The cluster keeps its own proportions. */
  align-content: start;
}

.shield[data-pos='1'] { grid-column: 1; grid-row: 1; }
.shield[data-pos='2'] { grid-column: 3; grid-row: 1; }
.shield[data-pos='3'] { grid-column: 2; grid-row: 1 / span 2; align-self: center; }
.shield[data-pos='4'] { grid-column: 1; grid-row: 2; }
.shield[data-pos='5'] { grid-column: 3; grid-row: 2; }

/* The centre carries the code, so it is drawn larger, as it is in the
   lockup. */
.shield--lead .shield__mark {
  width: var(--ph-lead-w);
  height: calc(var(--ph-lead-w) * 1.1464);
}

.shield {
  position: relative;
  display: grid;
  justify-items: center;
  align-content: start;
  row-gap: clamp(5px, 0.6vw, 9px);
  padding: 2px 1px 6px;
  /* A reliable target on a phone, in both directions, and the gaps in the
     formation keep neighbouring targets from touching. */
  min-width: 44px;
  min-height: 44px;
  /* The button is exactly its cell, so two targets can never overlap: the
     grid's own columns and gaps keep them apart. */
  width: 100%;
  cursor: pointer;
  transform-origin: var(--fs-ox, 50%) var(--fs-oy, 50%);
  transform: translate(var(--fs-x, 0px), var(--fs-y, 0px)) scale(var(--fs-s, 1));
  transition: transform 720ms var(--ease-out), opacity 420ms var(--ease-out);
  will-change: auto;
}

.shield__mark {
  display: block;
  width: var(--ph-shield-w);
  /* Every mark takes the height of the tallest, so the five names beneath
     sit on one line while the silhouettes keep their own chevron heights. */
  height: var(--ph-tall);
}

.shield__mark svg {
  display: block;
  width: 100%;
  height: auto;
  overflow: visible;
  /* The symbol's silhouette is filled with currentColor and its fold, the
     right half in shadow, with a fixed black at 22 percent. A <use> renders in
     a shadow tree this stylesheet cannot reach, so colour travels from here. */
  color: var(--f21-red);
  transition: color 260ms var(--ease-out), opacity 260ms var(--ease-out);
}

/* The five names, under their shields. In a compact formation a long name
   takes two lines and that is fine; what is not fine is two lines set at
   reading leading, which adds forty pixels to every rank of the cluster. The
   tracking stays, because that is what makes these read as an index. */
.shield__name {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 9px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  line-height: 1.15;
  text-align: center;
  color: var(--paper-dim);
  width: 100%;
  transition: color 260ms var(--ease-out), opacity 380ms var(--ease-out);
}

/* The five names stay visible at every width. They were hidden under 600 px
   when the formation was a rank of five across the screen and there was no
   room; on the diagonals there are three columns rather than five, so a name
   has a third of the cluster and can be read. All five discoverable is the
   point of a formation. */
@media (max-width: 600px) {
  .shield__name {
    font-size: 8.5px;
    letter-spacing: 0.1em;
  }
}

@media (min-width: 721px) {
  .shield__name { font-size: 10px; letter-spacing: 0.16em; }
}

@media (min-width: 1440px) {
  .shield__name { font-size: 11px; letter-spacing: 0.18em; }
}

.shield:hover .shield__mark svg,
.shield:focus-visible .shield__mark svg {
  color: var(--f21-red-hi);
}

.shield:hover .shield__name,
.shield:focus-visible .shield__name {
  color: var(--paper);
}

/* Selection. The formation stays whole and red: the open discipline stands
   forward, the other four step back, and nothing is removed or resized.

   8 September: back at 0.38 the four all but disappeared the moment Moral
   Courage was pressed, and the picture that left on screen was one shield
   alone — the opposite of what the code says. Selection and weakness are not
   the same idea. At 0.72 the four are plainly still there, holding the
   flanks, and the open one still stands forward: the mark lifts, goes to the
   brighter red, takes its rule and carries aria-pressed. Four signals, none
   of them the disappearance of the other four. */
.phalanx.has-open .shield:not([aria-pressed='true']) .shield__mark svg {
  opacity: 0.72;
}

.phalanx.has-open .shield:not([aria-pressed='true']) .shield__name {
  color: var(--paper-dim);
}

/* THE GUARD. What the code claims is a relationship — the four cover the
   centre's flanks — and the layout only implied it by proximity.

   The first attempt drew a short rule out of each flanking shield toward the
   centre. On a phone the columns are wider than the shields in them, so the
   four rules landed as loose dashes near the middle and read as damage. This
   is one line instead: the rank line the lockup itself has, drawn across the
   formation at the height of the centre's mass, passing behind all five. It
   says the four stand on the same line as the centre, which is what a phalanx
   is, and there is nothing on screen that a paragraph would have to explain.

   Quiet at rest; it lights when Moral Courage is the open discipline, which is
   the moment the claim is being made. */
.phalanx { position: relative; }

.phalanx__line {
  position: absolute;
  left: 6%;
  right: 6%;
  /* The centre shield spans both rows and is centred in them, so the middle of
     the rank is the middle of its mass. */
  top: 50%;
  height: 1px;
  margin: 0;
  overflow: visible;
  background: linear-gradient(to right,
    rgba(220, 34, 39, 0) 0%,
    rgba(220, 34, 39, 0.55) 12%,
    rgba(220, 34, 39, 0.55) 88%,
    rgba(220, 34, 39, 0) 100%);
  opacity: 0.34;
  transition: opacity var(--dur-mid) var(--ease-out);
  pointer-events: none;
  z-index: 0;
}

.phalanx:has(.shield--lead[aria-pressed='true']) .phalanx__line { opacity: 0.9; }

/* The shields sit over it, so the line passes behind the marks rather than
   through them. */
.shield { z-index: 1; }

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

/* The travelling marker that ran along the old rank is retired with it. */
/* The travelling marker belonged to the rank and is retired with it. The
   element stays in the markup so formation.js keeps a stable target and the
   no-script layout is unchanged. */
.phalanx__marker { display: none; }

/* The starting pose is written with every transition off, then released. */
[data-fs60p-instant] .shield,
[data-fs60p-instant] .shield__name,
[data-fs60p-instant] .phalanx__line,
[data-fs60p-instant] .phalanx__mark,
[data-fs60p-instant] .shield__mark { transition: none !important; }

/* The compact pose. The transforms themselves are written by fs60p.js; the
   stylesheet only says what disappears while the mark is whole. */
[data-fs60p='phalanx'] .shield__name { opacity: 0; }
[data-fs60p='phalanx'] .phalanx__line { opacity: 0; }
[data-fs60p='phalanx'] .shield .shield__mark svg { opacity: 1; color: var(--f21-red); }
[data-fs60p='phalanx'] .shield__mark { transform: none; }
[data-fs60p='phalanx'] .phalanx__mark { opacity: 1; }
/* Deployed, the mark is gone. It is the pose the shields came out of, and in
   the new composition it sits behind them rather than above them, where any
   visible remnant reads as a second logo printed under the formation. */
[data-fs60p='deployed'] .phalanx__mark { opacity: 0; }

/* Reduced motion never poses. The formation is deployed, still, and usable. */
@media (prefers-reduced-motion: reduce) {
  .shield,
  .shield__mark,
  .phalanx__mark,
  .phalanx__marker,
  .phalanx__line { transition: none; }
  [data-fs60p] .shield { --fs-x: 0px; --fs-y: 0px; --fs-s: 1; }
  [data-fs60p] .shield__name { opacity: 1; }
  [data-fs60p] .phalanx__line { opacity: 0.34; }
}

/* --- The discipline panel --------------------------------------------------
   Resolved, the whole code at a glance: five rows, index, name, imperative,
   each a button that opens that discipline. Open, one discipline at three
   columns of argument and five of photograph. */

.discipline {
  margin-top: var(--stack-lg);
}

.glance {
  display: grid;
  border-top: 1px solid var(--ink-line-soft);
}

.glance__btn {
  width: 100%;
  display: grid;
  grid-template-columns: 4ch minmax(0, 1fr);
  column-gap: clamp(14px, 2vw, 28px);
  row-gap: 6px;
  align-items: baseline;
  padding: clamp(16px, 2vw, 26px) 0;
  border-bottom: 1px solid var(--ink-line-soft);
  text-align: left;
  color: inherit;
  transition: background var(--dur-fast) var(--ease-out);
}

.glance__btn:hover,
.glance__btn:focus-visible {
  background: linear-gradient(90deg, rgba(220, 34, 39, 0.08), transparent 60%);
}

.glance__no {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: var(--t-small);
  letter-spacing: 0.1em;
  color: var(--f21-red-hi);
}

.glance__name {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(22px, 3.4vw, 42px);
  line-height: 1;
  text-transform: uppercase;
  letter-spacing: -0.005em;
  color: var(--paper);
}

.glance__imperative {
  grid-column: 2;
  font-family: var(--font-text);
  font-size: var(--t-body-lg);
  line-height: 1.5;
  color: var(--paper-dim);
  max-width: 52ch;
}

@media (min-width: 721px) {
  .glance__btn {
    grid-template-columns: 5ch minmax(0, 11fr) minmax(0, 13fr);
    align-items: baseline;
  }
  .glance__imperative { grid-column: 3; }
}

.discipline__panel {
  row-gap: var(--stack-lg);
  align-items: start;
}

/* Scripts running: the panels wait for a selection. Scripts off: everything
   is on the page, the code at a glance and then all five disciplines in
   full. */
html:not(.no-js) .discipline__panel:not(.is-open) { display: none; }
html:not(.no-js) .discipline__glance.is-hidden { display: none; }
.no-js .discipline__panel { margin-top: var(--stack-xl); }
.no-js .discipline__close { display: none; }

.discipline__text {
  display: flex;
  flex-direction: column;
  align-items: stretch;
}

.discipline__text > .discipline__close {
  align-self: flex-start;
}

/* The index is an index. In the stage's middle column a numeral at seven
   viewport units would be the largest thing in the composition and would read
   as a second headline, so it is held to the scale of a label set large. */
.discipline__index {
  font-family: var(--font-display);
  font-size: clamp(26px, 2.4vw, 38px);
  font-weight: 700;
  line-height: 0.9;
  color: var(--ink-line);
  letter-spacing: -0.01em;
}

.discipline__name {
  margin-top: var(--cluster-gap);
  font-size: clamp(28px, 3vw, 46px);
}

.discipline__imperative {
  margin-top: var(--cluster-gap);
  font-family: var(--font-text);
  font-weight: 500;
  font-size: var(--t-deck);
  line-height: 1.4;
  color: var(--paper);
  max-width: 24ch;
}

.discipline__body {
  margin-top: var(--stack-md);
}

.discipline__cite {
  margin-top: var(--stack-md);
  display: flex;
  align-items: center;
  gap: 12px;
}

.discipline__cite::before {
  content: '';
  width: 22px;
  height: 1px;
  background: var(--f21-red);
  flex: none;
}

.discipline__close {
  margin-top: var(--stack-lg);
}

.discipline__plate {
  margin: 0;
}

.discipline__panel.is-open {
  animation: swap-in 460ms var(--ease-out);
}

@keyframes swap-in {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* A film that cannot play leaves its poster behind it rather than a black
   frame: the poster is painted on the frame as well as on the element. */
.film__frame {
  background: #000 url('../video/f21-commercial-60-poster.jpg') center / contain no-repeat;
}

/* --- The feature film controls -----------------------------------------------
   Two controls, upper right, on their own plate so they read against any
   frame. 44px targets, visible focus. */

.film__controls {
  position: absolute;
  top: clamp(12px, 1.6vw, 22px);
  right: clamp(12px, 1.6vw, 22px);
  z-index: 3;
  display: flex;
  gap: 8px;
}

.film__ctl {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
  min-width: 44px;
  padding: 0 14px;
  background: rgba(12, 15, 15, 0.82);
  border: 1px solid rgba(244, 245, 244, 0.22);
  color: var(--paper);
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 10.5px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  transition: border-color var(--dur-fast) var(--ease-out), background var(--dur-fast) var(--ease-out);
}

.film__ctl svg {
  width: 18px;
  height: 18px;
  flex: none;
}

.film__ctl:hover,
.film__ctl:focus-visible {
  border-color: var(--f21-red-hi);
  background: rgba(12, 15, 15, 0.94);
}

.film__ctl[aria-pressed='true'] {
  border-color: var(--f21-red);
}

.film__ctl[aria-pressed='true'] .film__cross { display: none; }

@media (max-width: 600px) {
  .film__ctl span { position: absolute; width: 1px; height: 1px; overflow: hidden;
    clip: rect(0, 0, 0, 0); white-space: nowrap; }
  .film__ctl { padding: 0 12px; }
}

/* Shown only when autoplay was refused. It takes the space the poster already
   holds, so nothing shifts. */
.film__play {
  position: absolute;
  inset: 0;
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 14px;
  width: 100%;
  color: var(--paper);
  font-family: var(--font-display);
  font-weight: 700;
  font-size: var(--t-micro);
  letter-spacing: 0.2em;
  text-transform: uppercase;
  background: rgba(12, 15, 15, 0.28);
}

.film__play svg {
  width: 44px;
  height: 44px;
  padding: 10px;
  border: 1px solid rgba(244, 245, 244, 0.5);
}

.film__play[hidden] { display: none; }

.film__frame.is-audible .film__ctl--sound { border-color: var(--f21-red); }

/* --- Declared plates -------------------------------------------------------------
   A photograph that carries its own line. The copy sits inside the frame on
   a local gradient, never a wash over the whole picture, and inside the
   safe area on every crop. */

.plate-declared {
  position: relative;
}

.plate-declared__copy {
  position: absolute;
  inset: auto 0 0 0;
  z-index: 2;
  padding: clamp(64px, 12vw, 160px) clamp(18px, 3.2vw, 56px) clamp(18px, 3vw, 44px);
  background: linear-gradient(to top, rgba(6, 8, 8, 0.86), rgba(6, 8, 8, 0.46) 48%, transparent);
  pointer-events: none;
}

.plate-declared__line {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(19px, 3.1vw, 50px);
  line-height: 1.02;
  letter-spacing: -0.005em;
  text-transform: uppercase;
  color: var(--paper);
  max-width: 22ch;
  text-wrap: balance;
}

.plate-declared__copy--center {
  inset: 0;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  text-align: center;
  padding-bottom: clamp(22px, 5vw, 72px);
  background: linear-gradient(to top, rgba(6, 8, 8, 0.82), rgba(6, 8, 8, 0.3) 46%, rgba(6, 8, 8, 0.06));
}

.plate-declared__called {
  /* Full width, centred by text-align rather than by flex shrink to fit, so
     the box is fixed by the frame while its glyphs resolve. */
  width: 100%;
  text-align: center;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(30px, 6.4vw, 108px);
  line-height: 0.92;
  letter-spacing: -0.01em;
  text-transform: uppercase;
  color: var(--f21-red-hi);
  text-shadow: 0 2px 24px rgba(0, 0, 0, 0.45);
}

@media (max-width: 767px) {
  .plate-declared--called .editorial__frame { aspect-ratio: 16 / 9; }
  .plate-declared__copy--center { padding-bottom: 16px; }
}

/* --- Form ---------------------------------------------------------------------- */

.enlist {
  border: 1px solid var(--ink-line);
  background: var(--ink-raised);
  padding: clamp(22px, 3.4vw, 40px);
}

.enlist__fields {
  display: grid;
  gap: var(--stack-md);
  margin-top: var(--stack-md);
}

@media (min-width: 721px) {
  .enlist__fields {
    grid-template-columns: 1fr 1fr;
  }

  .field--wide {
    grid-column: 1 / -1;
  }
}

.field {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.field label {
  font-family: var(--font-text);
  font-size: var(--t-micro);
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--paper-dim);
}

/* A field is a box, not an underline. 8 September: an underline on a
   near-black panel is a hairline a man has to look for, and on a phone in
   daylight it disappears entirely — there was nothing on screen that read as
   somewhere to type. Each input now has its own slightly lighter charcoal,
   #2A3030, a full border, and comfortable padding, so the box itself says
   where the answer goes.

   16px is the floor at which iOS Safari stops zooming the page on focus, and
   every input here clears it. */
.field input {
  /* A visible edge, not the hairline the rest of the page divides with: this
     one has to say "type here" across a dark panel in daylight. */
  border: 1px solid #414a4a;
  border-radius: 0;
  padding: 13px 14px;
  font-family: var(--font-text);
  font-size: max(16px, var(--t-body));
  color: var(--paper);
  background: #2a3030;
  transition: border-color var(--dur-fast) var(--ease-out),
    background-color var(--dur-fast) var(--ease-out),
    box-shadow var(--dur-fast) var(--ease-out);
}

.field input::placeholder {
  color: var(--paper-faint);
}

.field input:hover {
  border-color: var(--paper-faint);
}

.field input:focus {
  border-color: var(--f21-red-hi);
  background: #313838;
  box-shadow: inset 0 0 0 1px var(--f21-red-hi);
  outline: none;
}

/* Autofill. Every engine paints its own near-white over a filled field, and
   the box goes from charcoal to white with grey text the moment a password
   manager touches it. The inset shadow is the one property those styles do
   not override, so the box is painted with it and the text colour is forced. */
.field input:-webkit-autofill,
.field input:-webkit-autofill:hover,
.field input:-webkit-autofill:focus {
  -webkit-text-fill-color: var(--paper);
  -webkit-box-shadow: inset 0 0 0 1000px #2a3030;
  box-shadow: inset 0 0 0 1000px #2a3030;
  caret-color: var(--paper);
  transition: background-color 100000s ease 0s;
}

.enlist__foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--stack-md);
  margin-top: var(--stack-lg);
}

.enlist__status {
  font-family: var(--font-text);
  font-size: var(--t-micro);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--paper-dim);
  max-width: 40ch;
  line-height: 1.6;
}

.enlist__status[data-state='pending'] {
  color: var(--paper-dim);
  border-left: 1px solid var(--f21-red);
  padding-left: 14px;
}

/* --- Reveal ------------------------------------------------------------------- */

[data-reveal] {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity 760ms var(--ease-out), transform 760ms var(--ease-out);
  transition-delay: var(--reveal-delay, 0ms);
}

[data-reveal].is-in {
  opacity: 1;
  transform: none;
}

/* No script, no observer: nothing may stay hidden. */
.no-js [data-reveal] {
  opacity: 1;
  transform: none;
}

@media (prefers-reduced-motion: reduce) {
  [data-reveal] {
    opacity: 1;
    transform: none;
  }
}

/* --- Installed media plates ------------------------------------------------
   Real photography and film, mounted at declared ratios so nothing shifts on
   load. The plate placeholder system above stays for any position still
   awaiting an asset. */

.plate-media {
  position: relative;
  overflow: hidden;
  background: var(--ink-raised);
  border: 1px solid var(--ink-line);
}

.plate-media > img,
.plate-media > video,
.plate-media > picture > img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.plate-media--21x9 { aspect-ratio: 21 / 9; }
.plate-media--16x9 { aspect-ratio: 16 / 9; }
.plate-media--4x3  { aspect-ratio: 4 / 3; }
.plate-media--3x4  { aspect-ratio: 3 / 4; }

@media (max-width: 720px) {
  .plate-media--21x9 { aspect-ratio: 4 / 5; }
  .plate-media--16x9 { aspect-ratio: 4 / 5; }
}

.plate-video {
  cursor: pointer;
}

.plate-video::-webkit-media-controls-panel {
  background-image: linear-gradient(transparent, rgba(12, 15, 15, 0.7));
}

/* --- Download ------------------------------------------------------------- */

.download {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--stack-md);
  margin-top: var(--stack-lg);
  padding-bottom: var(--stack-lg);
  border-bottom: 1px solid var(--ink-line);
}

.download__meta {
  color: var(--paper-faint);
}

/* --- Inline link ------------------------------------------------------------ */

.link {
  color: var(--paper);
  text-decoration: none;
  border-bottom: 1px solid var(--f21-red);
  padding-bottom: 2px;
  transition: color var(--dur-fast) var(--ease-out),
    border-color var(--dur-fast) var(--ease-out);
}

.link:hover,
.link:focus-visible {
  color: var(--f21-red-hi);
  border-color: var(--f21-red-hi);
}

/* --- Notice ------------------------------------------------------------------
   Used wherever the site has to say plainly what is not connected yet. It is
   never dressed up as an offer. */

.notice {
  margin-top: var(--stack-lg);
  padding: 4px 0 4px 20px;
  border-left: 2px solid var(--f21-red);
  max-width: 74ch;
  font-family: var(--font-text);
  font-size: var(--t-body);
  line-height: 1.6;
  color: var(--paper-dim);
}

.notice b {
  display: inline-block;
  margin-right: 8px;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: var(--t-small);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--paper);
}

.notice--tight {
  margin-top: var(--stack-md);
}

/* --- Footer ----------------------------------------------------------------
   Shared by every page, which is why it lives here and not in movements.css. */

.colophon {
  border-top: 1px solid var(--ink-line);
  padding-block: var(--stack-xl) var(--stack-lg);
  background: var(--ink-deep);
}

.colophon__grid {
  row-gap: var(--stack-lg);
}

.colophon__phalanx {
  width: clamp(150px, 14vw, 210px);
  height: auto;
  color: var(--paper);
}

.colophon__tagline {
  position: relative;
  margin-top: var(--stack-md);
  padding-left: 28px;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: var(--t-small);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--paper);
}

/* The signal stays in the rule rather than in the type: red does not clear
   4.5:1 on this ground, so it never sets small text. */
.colophon__tagline::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0.62em;
  width: 18px;
  height: 2px;
  background: var(--f21-red);
}

.colophon__list {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-top: var(--stack-md);
}

.colophon__list a,
.colophon__list li {
  font-family: var(--font-text);
  font-size: var(--t-micro);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--paper-dim);
  transition: color var(--dur-fast) var(--ease-out);
}

.colophon__list a:hover,
.colophon__list a:focus-visible {
  color: var(--paper);
}

.colophon__list li[data-pending] {
  color: var(--paper-faint);
  display: flex;
  align-items: baseline;
  gap: 8px;
}

.colophon__list li[data-pending]::after {
  content: 'PENDING';
  color: var(--f21-red-hi);
  font-size: 9px;
  letter-spacing: 0.16em;
}

.colophon__base {
  display: flex;
  flex-wrap: wrap;
  gap: var(--stack-md);
  justify-content: space-between;
  align-items: baseline;
  margin-top: var(--stack-xl);
  padding-top: var(--stack-md);
  border-top: 1px solid var(--ink-line);
}

/* --- The icon family --------------------------------------------------------
   One size, one weight, one hit area, everywhere. Every glyph is a <use> of a
   symbol in the page's own sprite, drawn from the supplied Quantico Bold UI
   set on its 256 canvas; docs/ICON-AUDIT.md records which file each came from
   and names the one pair the set does not contain.

   The box is 1em so an icon takes the size of the control it sits in, and
   currentColor so it takes its colour. Controls that are icon only carry
   their name in an .sr-only span rather than on the svg, which keeps the name
   in one place whether or not the sprite loaded. */
.icon {
  width: 1em;
  height: 1em;
  flex: none;
  fill: currentColor;
  color: inherit;
}

/* --- Disclosure ------------------------------------------------------------
   An expandable paragraph in place: <details> and <summary>, so it opens
   without script, keeps its own keyboard behaviour, and is found by in-page
   search when open. Closing restores the compact layout exactly; nothing
   moves except the height of this block. */

.disclose {
  margin-top: var(--stack-md);
  border-top: 1px solid var(--ink-line);
}

.disclose__summary {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 14px 0;
  min-height: 44px;
  cursor: pointer;
  list-style: none;
  color: var(--paper-dim);
  font-family: var(--font-display);
  font-size: var(--t-micro);
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  transition: color var(--dur-fast) var(--ease-out);
}

.disclose__summary::-webkit-details-marker { display: none; }

.disclose__summary:hover,
.disclose[open] .disclose__summary {
  color: var(--paper);
}

.disclose__arrow {
  font-size: 15px;
  color: var(--f21-red);
  transition: transform var(--dur-mid) var(--ease-out);
}

.disclose[open] .disclose__arrow { transform: rotate(180deg); }

/* The revealed paragraph takes the width of its container, which is the
   reading column the disclosure sits in — never the label's width. */
.disclose__body {
  padding-bottom: var(--stack-md);
  width: 100%;
  max-width: none;
}

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

/* Eight destinations in the footer's Explore column is a tall list on a
   desktop and a short one on a phone; two columns above the phone breakpoint,
   one below it. */
@media (min-width: 768px) {
  .colophon__list--two {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    column-gap: 20px;
  }
}


/* ==========================================================================
   THE COPY FOLLOWS THE LINE (copy-reveal.js), 8 September, evening.

   The paragraph keeps its box and its text throughout; only its ink is held
   while an aria-hidden duplicate, laid exactly over it, populates line by
   line behind the red leader that redline.js draws. There is no rule of its
   own here any more: one leader per editorial group, and it is the red line.

   Every rule is gated on a class the script adds and removes, so without the
   script, with reduced motion, or after the event, the paragraph is exactly
   what the stylesheet made it. The held ink is declared important because the
   paragraphs it applies to carry their own colour rules in later sheets, and
   a held paragraph must be held entirely — a link keeping its colour would
   print twice.
   ========================================================================== */

.is-copy-armed,
.is-copy-live,
:is(.is-copy-armed, .is-copy-live) :not(.copy-dup, .copy-dup *) {
  color: transparent !important;
}

.copy-dup {
  position: absolute;
  inset: 0;
  display: block;
  pointer-events: none;
  user-select: none;
  color: var(--copy-ink, var(--paper));
  font: inherit;
  letter-spacing: inherit;
  text-align: inherit;
  white-space: inherit;
  hyphens: inherit;
}

.copy-dup a { color: inherit; }

.cg { display: inline; }

/* Under reduced motion the script never arms a paragraph and settles any it
   already had the moment the preference changes; nothing here is drawn. */
@media (prefers-reduced-motion: reduce) {
  .copy-dup { display: none; }
}
