/* ============================================================================
   UNIÓN , 04 Navigation, header, footer. Lane N owns this file.

   NO hex, NO font name, NO easing curve, NO duration in here. Every value is a
   var() off tokens.css. The one documented exception in the system, the mask
   gradient's #000 / #0000 alpha stencil, is not needed on this page: the only
   fade is the .pattern-slot's own, which lives in devices.css.

   Everything here composes from the seven devices. The phone menu, the fold-open
   totem and the desktop header's mobile form are all .d-totem. The blades are
   the one new shape on the page, and they are drawn (clip-path point, swings on
   a fixing), not a rectangle with a border.

   THE FRAMED SPECIMEN RULE. Headers, menus and footers are the components that
   most want to be `position:fixed` to the real viewport. On a spec page that is
   wrong twice over: it would escape the stage and it would stop the component
   being liftable. So every one of them is shown INSIDE a frame, .n-frame, which
   is a box with its own scroll and its own containing block. Sticky and fixed
   resolve against the frame, so the behaviour is REAL and still contained.
   ============================================================================ */

/* ----------------------------------------------------------------------------
   THE FRAME , a desktop specimen and a 390 phone specimen.
   A frame is a window onto a page, not a picture of one. It scrolls, and
   anything inside that is sticky sticks to the frame's top edge.
   ---------------------------------------------------------------------------- */
.n-frame{position:relative;background:var(--cream);color:var(--black);
  border:var(--rule-heavy) solid var(--black);border-radius:var(--radius-slab);
  overflow:auto;overscroll-behavior:contain;
  /* the frame is the containing block for anything fixed inside it, so a header
     that is position:fixed on the real site stays inside this window here */
  transform:translateZ(0);
  height:var(--frame-h,420px);width:100%;max-width:var(--frame-w,none)}
.n-frame--dark{background:var(--black);color:var(--cream);
  --ground:var(--black);--ink:var(--cream);--focus-colour:var(--focus-colour-on-dark)}
.n-frame--coral{background:var(--coral);--ground:var(--coral)}
.n-frame--tall{--frame-h:560px}
.n-frame--short{--frame-h:300px}
/* the 390 phone specimen. A real 390 viewport width, so everything inside sees
   the phone's own breakpoints via a container query, not the page's width. */
/* MEASURED, first render: at 620px the six flags plus the top bar and the foot
   overflowed and the first flag was cut off at the top. 780px holds the whole
   menu at its approved proportions, which is the right fix: the panel gets
   taller, the flags do not get thinner.

   MEASURED AGAIN after the rewrite: inside a flex row this frame was being
   SQUEEZED to about 90px, which clipped every label and made the starred
   component unrecognisable. A phone specimen is a fixed 390 and never flexes:
   width, flex:none and max-width are all required, not just --frame-w. */
.n-frame--phone{--frame-w:390px;--frame-h:780px;
  width:390px;max-width:100%;flex:0 0 auto;
  container-type:inline-size;container-name:phone}
/* MEASURED, first render: an absolutely positioned label inside the frame sat on
   top of whatever the frame's first child was, and on the announcement strip it
   landed directly over the marquee's words. The label sits ABOVE the frame now,
   in flow, where it cannot collide with anything. */
.n-frame__label{display:inline-block;margin-bottom:var(--s2);
  background:var(--black);color:var(--cream);
  font:700 var(--size-micro)/1 var(--font);letter-spacing:var(--track-micro);
  text-transform:uppercase;padding:5px var(--s2)}
/* the filler under a frame's header, so scrolling inside the frame is real and a
   sticky header has something to stick over. Never content, just ruled paper. */
.n-frame__fill{padding:var(--s5);display:grid;gap:var(--s3)}
.n-frame__fill i{display:block;height:var(--rule);background:var(--hairline)}
.n-frame__fill i:nth-child(3n){width:62%}
.n-frame__fill i:nth-child(4n){width:84%}
.n-frame--dark .n-frame__fill i{background:var(--hairline-on-dark)}
/* two frames side by side: the desktop one takes the space, the phone is fixed.
   A label in the row is a block of its own, so it captions the frame after it
   rather than sitting beside it. */
.n-pair{display:flex;flex-wrap:wrap;gap:var(--s6);align-items:flex-start}
.n-pair > .n-frame:not(.n-frame--phone){flex:1 1 520px;min-width:0}
/* a captioned specimen: the label above its own frame, the pair kept together.
   MEASURED, second render: two 390 phone frames side by side inside a 390
   viewport squeezed each to about 110px, which wrapped the menu's flags onto two
   lines and made the starred component unrecognisable. A phone specimen is never
   allowed to be narrower than the phone it documents: below 900px they stack. */
.n-spec{flex:0 0 auto;min-width:0;max-width:100%}
@media (max-width:900px){
  .n-pair{flex-direction:column}
  .n-spec,.n-pair > .n-frame{width:100%}
  .n-frame--phone{--frame-w:390px;max-width:100%}
}

/* ----------------------------------------------------------------------------
   N1 , THE DESKTOP HEADER
   Wordmark left at a size it can carry, five links, the language switch, the one
   pill. Square, no radius, one 2px rule on the bottom edge and nothing else.
   It is sticky INSIDE its frame, and it condenses on scroll.
   ---------------------------------------------------------------------------- */
.n-head{position:sticky;top:0;z-index:var(--z-raise);
  display:flex;align-items:center;gap:var(--s5);
  padding:var(--s4) var(--s5);
  background:var(--ground);color:var(--ink);
  border-bottom:var(--rule) solid var(--black);
  transition:padding var(--dur-state) var(--ease-out);
  container-type:inline-size;container-name:head}
.n-head--dark{background:var(--black);color:var(--cream);
  border-bottom-color:var(--cream);--focus-colour:var(--focus-colour-on-dark)}
.n-head--coral{background:var(--coral)}
/* the condensed state: the same header, less air, the mark smaller. It does not
   change colour, gain a shadow or blur: it just tightens. */
.n-head.is-scrolled{padding-top:var(--s2);padding-bottom:var(--s2)}
.n-head.is-scrolled .n-head__mark{width:var(--mark-sm,108px)}

.n-head__mark{width:var(--mark,152px);flex:none;
  transition:width var(--dur-state) var(--ease-out)}
.n-head__mark u-svg{width:100%}
.n-head--dark .n-head__mark path{fill:var(--cream)}

.n-head__links{display:flex;align-items:center;gap:var(--s5);
  margin:0 auto 0 var(--s4);padding:0;list-style:none;min-width:0}
.n-head__link{display:inline-flex;align-items:center;min-height:var(--tap-min);
  text-decoration:none;color:inherit;position:relative;
  font:900 15px/1 var(--font);font-stretch:var(--wdth-condensed);
  text-transform:uppercase;letter-spacing:.03em;white-space:nowrap}
/* the underline is a drawn stroke with the ribbon's round cap, not a border, and
   it draws along its length on hover rather than appearing. */
.n-head__link::after{content:"";position:absolute;left:0;right:0;bottom:var(--s2);
  height:var(--rule);background:currentColor;border-radius:var(--radius-round);
  transform:scaleX(0);transform-origin:0 50%;
  transition:transform var(--dur-draw) var(--ease-verb-draw)}
.n-head__link:hover::after,.n-head__link:focus-visible::after,
.n-head__link.is-hover::after,.n-head__link.is-focus::after{transform:scaleX(1)}
.n-head__link[aria-current="page"]::after{transform:scaleX(1)}
.n-head__link.is-focus{outline:var(--focus-width) solid var(--focus-colour);
  outline-offset:var(--focus-offset)}
.n-head__end{display:flex;align-items:center;gap:var(--s4);flex:none}
.n-head .u-pill{padding:var(--s3) var(--s4) var(--s3) var(--s5);font-size:16px}
.n-head .u-pill svg{width:26px}
/* the burger only exists under the phone width, and the links only above it.
   Measured on the FRAME, not the page, so the header can be lifted anywhere. */
.n-head__burger{display:none;appearance:none;cursor:pointer;
  width:var(--tap-min);height:var(--tap-min);padding:0;
  border:var(--rule) solid var(--black);background:var(--care);
  place-items:center;gap:var(--s1)}
.n-head__burger i{display:block;width:20px;height:3px;background:var(--black);
  border-radius:var(--radius-round);grid-area:1/1;
  transition:transform var(--dur-bounce) var(--ease-verb-bounce)}
.n-head__burger i:nth-child(1){transform:translateY(-7px)}
.n-head__burger i:nth-child(3){transform:translateY(7px)}
.n-head__burger[aria-expanded="true"] i:nth-child(1){transform:rotate(45deg)}
.n-head__burger[aria-expanded="true"] i:nth-child(2){transform:scaleX(0)}
.n-head__burger[aria-expanded="true"] i:nth-child(3){transform:rotate(-45deg)}
@container head (max-width:640px){
  .n-head__links,.n-head__end .u-pill{display:none}
  .n-head__burger{display:grid}
  .n-head__mark{width:var(--mark-sm,108px)}
}

/* ----------------------------------------------------------------------------
   N2 , THE ANNOUNCEMENT STRIP
   The alert totem bar, above the header. Restated from .d-totem, not redefined:
   this rule only places it and gives it a dismissed state.
   ---------------------------------------------------------------------------- */
.n-strip{position:relative;z-index:var(--z-overlay)}
.n-strip.is-dismissed{display:none}
/* A SPECIMEN modifier, not part of the component: it holds the marquee at its
   start so the first message is whole in a still. Without it the shot catches
   the run mid-loop with the leading words already scrolled out of the track,
   which reads as clipped text rather than as motion. Never ship this class. */
/* the device sets the `animation` SHORTHAND under `.is-live`, which resets
   animation-delay to 0 and outranks a single class, so this selector has to
   match that specificity or it silently does nothing (measured: delay 0s).
   A delay was still not enough, because the shot's mid-interaction pass fires
   after it expires and caught the run part-scrolled again. The specimen is
   PAUSED outright: the pulse still shows the bar is live, and the message is
   whole and readable, which is what a documentation still has to show. */
.n-strip--still .d-totem__bar--alert.is-live .d-totem__run{
  animation-play-state:paused;animation-delay:0s}

/* ----------------------------------------------------------------------------
   N3 , THE PHONE MENU AS A FULL-HEIGHT TOTEM   (starred: set-02 N3)
   MEASURED off the starred shot at 18.29.12: a cream bar across the top with the
   wordmark and a yellow bordered close square; six flags below it filling the
   panel exactly, each 1/6 of the height, each a thumb-deep colour bar with a
   solid-headed arrow at its right; a 2px black rule between flags and nothing
   round anywhere. The panel is BLACK behind them, which is what the cream flag
   sits on so it reads as a flag rather than as the page.
   ---------------------------------------------------------------------------- */
.n-menu{position:absolute;inset:0;display:flex;flex-direction:column;
  background:var(--black);z-index:var(--z-overlay);visibility:hidden}
.n-menu[data-open="1"]{visibility:visible}
.n-menu__top{flex:0 0 auto;display:flex;align-items:center;justify-content:space-between;
  gap:var(--s4);padding:var(--s3) var(--s4);background:var(--cream);
  border-bottom:var(--rule) solid var(--black)}
.n-menu__top u-svg{width:112px}
.n-menu__close{appearance:none;cursor:pointer;
  width:var(--tap-min);height:var(--tap-min);flex:none;padding:0;
  display:grid;place-items:center;
  border:var(--rule) solid var(--black);background:var(--care);color:var(--black);
  font:900 20px/1 var(--font);font-stretch:var(--wdth-condensed)}
/* the flags. .d-totem carries the bar; this only makes the stack fill the panel
   and gives each flag its equal share, which is what makes every target deeper
   than a thumb pad whatever the phone. */
/* PORTED AS APPROVED, from the lab `.n3-flag` rules behind the starred shot:
   flex:1 1 0 so each flag is exactly 1/6 of the panel, `padding:0 16px`, the
   label at 21px 900 condensed caps, and a 30px arrow. The panel is sized to
   hold six, so the panel gets taller rather than the flags getting thinner. */
.n-menu .d-totem{flex:1 1 auto;min-height:0}
.n-menu .d-totem__bar{flex:1 1 0;min-height:0;
  display:flex;align-items:center;justify-content:space-between;gap:var(--s3);
  padding:0 var(--s4);
  font:900 21px/1 var(--font);font-stretch:var(--wdth-condensed);
  border-top:var(--rule) solid var(--black)}
/* the flag's arrow is a DRAWN LINE, not the totem's solid block: measured off
   the starred shot and off the lab `.arw` rule (fill:none, round caps). The
   state cells use the same arrow, so a cell matches the live component. */
.n-menu .d-totem__arrow,.n-flag-arw{width:30px;height:auto;flex:none}
.n-menu .d-totem__arrow path,.n-flag-arw path{fill:none;stroke:currentColor;
  stroke-width:14;stroke-linecap:round;stroke-linejoin:round}

/* PORTED AS APPROVED: the colour order Louis starred, in his exact sequence.
   LINEUP pink · SET TIMES coral · THE SITE yellow · GETTING HERE cream ·
   TICKETS pink · QUESTIONS yellow. This is NOT the --stack 4n cycle, so it is
   set explicitly here rather than inherited from the device. */
.n-menu .d-totem > :nth-child(1).d-totem__bar{background:var(--pink)}
.n-menu .d-totem > :nth-child(2).d-totem__bar{background:var(--coral)}
.n-menu .d-totem > :nth-child(3).d-totem__bar{background:var(--yellow)}
.n-menu .d-totem > :nth-child(4).d-totem__bar{background:var(--cream)}
.n-menu .d-totem > :nth-child(5).d-totem__bar{background:var(--pink)}
.n-menu .d-totem > :nth-child(6).d-totem__bar{background:var(--yellow)}
/* the flags DROP in from above, one after another, which is the verb the signage
   already does. Held off until the menu is open. */
.n-menu[data-open="1"] .d-totem__bar{animation:n-drop var(--dur-drop) var(--ease-verb-drop) backwards}
.n-menu .d-totem > :nth-child(1) .d-totem__bar{animation-delay:20ms}
.n-menu .d-totem > :nth-child(2) .d-totem__bar{animation-delay:80ms}
.n-menu .d-totem > :nth-child(3) .d-totem__bar{animation-delay:140ms}
.n-menu .d-totem > :nth-child(4) .d-totem__bar{animation-delay:200ms}
.n-menu .d-totem > :nth-child(5) .d-totem__bar{animation-delay:260ms}
.n-menu .d-totem > :nth-child(6) .d-totem__bar{animation-delay:320ms}
@keyframes n-drop{from{transform:translateY(-102%)}to{transform:translateY(0)}}
@media (prefers-reduced-motion:reduce){
  .n-menu[data-open="1"] .d-totem__bar{animation:none}
}
/* NO LANGUAGE BAR. Louis's starred menu is the top bar and six flags, nothing
   else. I had added a language row at the foot; it is not in the approved
   design and has been removed. If language belongs in the menu that is a
   separate PROPOSAL spec, not a change to the ported component. */

/* ----------------------------------------------------------------------------
   N4 , FINGERPOST BLADES   (starred: set-07 G7)
   MEASURED off the starred shot at 18.08.47: one black post down the middle, a
   black cap sign at the top, and pointed blades nailed alternately left and
   right, each with the soundwave at its inner end, a name, a walk time and a
   stroked arrow pointing the way it goes. The point is a clip-path, so there is
   no border to be cut off at the tip. Blades overlap the post by their own
   depth, which is what makes them read as nailed to it rather than butted.
   ---------------------------------------------------------------------------- */
/* PORTED AS APPROVED, from the lab build behind the starred shot. */
.n-post{position:relative;max-width:900px;margin-inline:auto;
  display:flex;flex-direction:column;align-items:center;gap:var(--s2);
  padding:var(--s2) 0}
.n-post::before{content:"";position:absolute;left:50%;top:0;bottom:0;
  width:16px;margin-left:-8px;background:var(--black)}
.n-post__cap{position:relative;z-index:var(--z-body);display:inline-block;
  margin-bottom:var(--s1);padding:var(--s2) var(--s4);
  background:var(--black);color:var(--cream);
  font:900 15px/1 var(--font);font-stretch:var(--wdth-condensed);
  text-transform:uppercase;letter-spacing:.06em}

.n-blade{position:relative;display:flex;align-items:center;gap:var(--s3);
  appearance:none;border:0;cursor:pointer;text-decoration:none;
  background:var(--dc,var(--primary));color:var(--black);text-align:left;
  width:min(420px,46vw);min-height:var(--tap-min);
  padding:var(--s3) var(--s5) var(--s3) var(--s5);
  font:900 clamp(17px,2vw,26px)/1 var(--font);font-stretch:var(--wdth-condensed);
  text-transform:uppercase;
  transition:transform var(--dur-swing) var(--ease-verb-swing)}
.n-blade--main{--dc:var(--stage-main)}
.n-blade--grove{--dc:var(--stage-grove)}
.n-blade--corner{--dc:var(--stage-corner)}
/* the plain blade. Cream on cream would vanish, so a blade with no stage colour
   takes the cream ground and earns its edge from the black type and soundwave on
   it, exactly as in the starred shot. */
/* PORTED AS APPROVED, with ONE forced substitution, recorded in evidence/N.md.
   Louis's blade has NO border: a border is sliced off at the arrowhead by the
   clip-path and leaves the blade unfinished, which is why the lab dropped it.
   But the lab's neutral blade is #efe6d2, a SIXTH colour this system does not
   have. Against the cream page --cream IS the ground, so with no border the
   blade vanished entirely and the render showed floating type.
   There is no faithful answer inside the five. Measured, all four alternatives:
     cream on the cream page  , the blade disappears, type floats (first render)
     a black inset rule       , the clip-path slices it off at the arrowhead
     post on a yellow stage   , the YELLOW blade then disappears instead
     neutral blade -> yellow  , two adjacent yellow blades, and the set loses
                                its neutral, which is half the blades
   So the approved value is carried over as a PROPOSED TOKEN and flagged for the
   planner. This is the one value on this page that is not already in tokens.css. */
/* PROPOSED TOKEN */
.n-blade--plain{--cream-2:#efe6d2;--dc:var(--cream-2)}
/* the point. A clip-path, so the blade ends in a real arrowhead rather than a
   rectangle with a triangle stuck on. It SWINGS on its nail, which is the
   transform-origin at the post end. */
/* MEASURED off the starred shot: the label on a right-pointer sits well in from
   the post (about 70px at his capture width), not hard against it, so the blade
   reads as a sign with air rather than a filled bar. --s8 is that inset. */
.n-blade[data-dir="right"]{align-self:flex-start;margin-left:50%;
  transform-origin:0 50%;padding-right:var(--s7);padding-left:var(--s8);
  clip-path:polygon(0 0,calc(100% - 28px) 0,100% 50%,calc(100% - 28px) 100%,0 100%)}
/* the mirror: the left-pointer's label sits right-aligned near the post, so the
   inset is on the RIGHT, and the arrow end keeps the point's clearance. */
.n-blade[data-dir="left"]{align-self:flex-end;margin-right:50%;
  transform-origin:100% 50%;flex-direction:row-reverse;text-align:right;
  padding-left:var(--s7);padding-right:var(--s8);
  clip-path:polygon(28px 0,100% 0,100% 100%,28px 100%,0 50%)}
/* MEASURED off the starred shot (18.08.47): the blades carry NO soundwave glyph.
   The lab markup has one on every blade, but the approved render does not: the
   blade is label, walk time, arrow and nothing else. Removed from every blade.
   The label then takes the space the glyph was holding, which is what gives the
   right-pointer its generous inset from the post and pushes the left-pointer's
   label back against the post, exactly as in the shot. */
.n-blade__name{flex:1 1 auto}
.n-blade__m{flex:none;font:700 var(--size-micro)/1 var(--font);
  letter-spacing:.12em;opacity:.7}
.n-blade__arw{width:32px;height:19px;flex:none}
.n-blade__arw path{fill:none;stroke:currentColor;stroke-width:3.4;
  stroke-linecap:round;stroke-linejoin:round}
.n-blade[data-dir="left"] .n-blade__arw{transform:scaleX(-1)}
/* SWING. A left-pointer swings the other way, because it hangs off the other
   side of the same nail. */
.n-blade[data-dir="right"]:hover,.n-blade[data-dir="right"]:focus-visible,
.n-blade[data-dir="right"].is-hover,.n-blade[data-dir="right"].is-focus{
  transform:rotate(-2.2deg) translateX(10px)}
.n-blade[data-dir="left"]:hover,.n-blade[data-dir="left"]:focus-visible,
.n-blade[data-dir="left"].is-hover,.n-blade[data-dir="left"].is-focus{
  transform:rotate(2.2deg) translateX(-10px)}
.n-blade.is-focus{outline:var(--focus-width) solid var(--focus-colour);
  outline-offset:calc(var(--focus-offset) * -1)}
.n-blade.is-disabled{opacity:.45;pointer-events:none;transform:none}
.n-post__foot{position:relative;z-index:var(--z-body);margin:var(--s2) 0 0;
  display:inline-block;padding:var(--s1) var(--s3);background:var(--ground);
  text-align:center}
@media (prefers-reduced-motion:reduce){
  .n-blade{transition:none}
}
/* at the phone width every blade points the way it is read, off one post at the
   left edge, because a right-to-left blade at 390 has nowhere to go. */
@media (max-width:620px){
  .n-post::before{left:12px;margin-left:0}
  /* MEASURED at 390: `calc(100% - 20px)` plus the 20px margin-left is exactly
     100%, and the blade then overflows its post by its own left offset. The
     40px accounts for both the offset and the margin, so the point stays inside. */
  .n-blade{width:calc(100% - 40px)}
  .n-blade[data-dir="right"],.n-blade[data-dir="left"]{
    align-self:flex-start;margin-left:20px;margin-right:0;
    flex-direction:row;text-align:left;transform-origin:0 50%;
    padding-left:var(--s4);padding-right:var(--s7);
    clip-path:polygon(0 0,calc(100% - 28px) 0,100% 50%,calc(100% - 28px) 100%,0 100%)}
  .n-blade[data-dir="left"] .n-blade__arw{transform:scaleX(-1)}
  .n-blade[data-dir="left"]:hover,.n-blade[data-dir="left"]:focus-visible,
  .n-blade[data-dir="left"].is-hover{transform:rotate(-2.2deg) translateX(10px)}
}

/* ----------------------------------------------------------------------------
   N5 , TOTEM BARS THAT FOLD OPEN   (starred: set-15 D9)
   MEASURED off the starred shot at 17.58.42: each bar is a totem bar on a plinth,
   a solid black offset slab behind it at about 6px right and 7px down, with a 3px
   black border on the bar itself. The bar does NOT tip: the answer is the black
   face that swings down off the bar's bottom edge on a hinge.
   This is .d-totem with a plinth and a hinge, not a new accordion.
   ---------------------------------------------------------------------------- */
.n-fold{max-width:780px;perspective:1200px}
.n-fold .d-totem__row{margin-bottom:var(--s3);transform-style:preserve-3d}
/* the plinth: an opaque black slab, offset. The bar must carry its own opaque
   ground or the slab shows through it, which is why the cream step in this stack
   is a real cream fill rather than the page showing through. */
/* PORTED AS APPROVED: the plinth is a ::before at z-index:-1 behind the bar,
   offset right and down, which is exactly the lab build behind the starred shot.
   It relies on the bar having an OPAQUE background and no stacking context, so
   do not add isolation or a positive z-index here. (A state cell that shows the
   bar must give it a real opaque ground; see the note in evidence/N.md.) */
.n-fold .d-totem__bar{position:relative;border:var(--rule-heavy) solid var(--black);
  padding:var(--s4) var(--s4);gap:var(--s4)}
/* MEASURED, fourth render: the lab draws the plinth as the BAR's own ::before at
   z-index:-1, which works only while the bar makes no stacking context. On
   hover the bar transforms (translateX 8px), which creates one, and the -1 layer
   then paints behind the bar's own background instead of behind the element: the
   hover cell rendered as a solid black box with the pink bar invisible.
   Same look, same offsets, same colours; the plinth is drawn by the ROW instead,
   which never transforms, so it cannot be trapped. */
/* the row is a grid whose FIRST track is the bar, so the plinth is placed in
   that track and takes the bar's own height whatever the question's length. */
.n-fold .d-totem__row{position:relative;display:grid;grid-template-rows:auto 1fr}
.n-fold .d-totem__row::before{content:"";grid-row:1;grid-column:1;
  margin:6px calc(var(--s1) * -1.5) -7px var(--s1);
  background:var(--black);z-index:var(--z-river)}
.n-fold .d-totem__bar{grid-row:1;grid-column:1;z-index:var(--z-body)}
.n-fold .d-totem__face{grid-row:2;grid-column:1}
.n-fold .d-totem > :nth-child(4n+2) .d-totem__bar{background:var(--cream)}
/* the hinge. The face swings down from edge-on to flat, so opening one is a
   thing turning towards you rather than a drawer sliding. */
.n-fold .d-totem__face{transform-origin:50% 0;transform:rotateX(-78deg);
  transition:grid-template-rows var(--dur-drop) var(--ease-out),
             transform var(--dur-drop) var(--ease-out),
             visibility 0s linear var(--dur-drop)}
.n-fold .d-totem__row.is-open .d-totem__face{transform:rotateX(0)}
.n-fold .d-totem__face p{padding:var(--s4) var(--s5)}
@media (prefers-reduced-motion:reduce){
  .n-fold .d-totem__face{transform:none;transition:none}
}

/* ----------------------------------------------------------------------------
   N6 , THE STICKY TICKET BAR (phone)
   The last thing on the screen, always. One pill and the one fact that decides
   whether the pill gets pressed. It is sticky to the BOTTOM of its frame.
   ---------------------------------------------------------------------------- */
.n-ticketbar{position:sticky;bottom:0;z-index:var(--z-overlay);
  display:flex;align-items:center;justify-content:space-between;gap:var(--s3);
  padding:var(--s3) var(--s4);background:var(--black);color:var(--cream);
  border-top:var(--rule-heavy) solid var(--cream);
  --focus-colour:var(--focus-colour-on-dark)}
.n-ticketbar__fact{min-width:0}
.n-ticketbar__fact b{display:block;font:900 17px/1 var(--font);
  font-stretch:var(--wdth-condensed);text-transform:uppercase}
.n-ticketbar__fact span{display:block;margin-top:var(--s1);opacity:.8;
  font:700 var(--size-micro)/1 var(--font);letter-spacing:var(--track-micro);
  text-transform:uppercase}
.n-ticketbar .u-pill{flex:none;padding:var(--s3) var(--s4) var(--s3) var(--s5);font-size:16px}
.n-ticketbar .u-pill svg{width:24px}

/* ----------------------------------------------------------------------------
   N7 , IN-PAGE SECTION NAV (the stage tabs pattern)
   Three stages, three colours, one chosen. The chosen tab is the only one with
   its stage colour filled; the others carry the colour as a soundwave only, so
   the row never becomes three equal buttons.
   ---------------------------------------------------------------------------- */
.n-tabs{display:flex;flex-wrap:wrap;gap:0;border-bottom:var(--rule) solid var(--black)}
.n-tab{appearance:none;border:0;cursor:pointer;background:none;color:inherit;
  display:inline-flex;align-items:center;gap:var(--s3);
  padding:var(--s3) var(--s5);min-height:var(--tap-min);
  font:900 clamp(15px,1.6vw,20px)/1 var(--font);font-stretch:var(--wdth-condensed);
  text-transform:uppercase;letter-spacing:.02em;
  transition:background var(--dur-state) var(--ease-out)}
.n-tab .d-wave{height:20px;gap:3px}
.n-tab .d-wave i{width:5px}
.n-tab[aria-selected="true"],.n-tab.is-selected{background:var(--stage)}
.n-tab:hover,.n-tab.is-hover{background:var(--stage)}
.n-tab.is-focus{outline:var(--focus-width) solid var(--focus-colour);
  outline-offset:calc(var(--focus-offset) * -1)}
.n-tab.is-disabled{opacity:.45;pointer-events:none}

/* ----------------------------------------------------------------------------
   N8 , BREADCRUMB, BACK TO TOP, SKIP LINK
   The three quiet ones. None of them gets a device: a breadcrumb that wears a
   totem bar is a totem bar pretending to be small print.
   ---------------------------------------------------------------------------- */
.n-crumbs{display:flex;flex-wrap:wrap;align-items:center;gap:var(--s2);
  margin:0;padding:0;list-style:none}
.n-crumbs a{display:inline-flex;align-items:center;min-height:var(--tap-min);
  text-decoration:none;border-bottom:var(--rule) solid currentColor}
.n-crumbs a:hover{background:var(--care)}
.n-crumbs li{font:700 var(--size-micro)/1 var(--font);letter-spacing:var(--track-micro);
  text-transform:uppercase;display:flex;align-items:center;gap:var(--s2)}
.n-crumbs li[aria-current="page"]{opacity:.6}
/* the separator is the soundwave's smallest bar, not a slash */
.n-crumbs li + li::before{content:"";width:3px;height:11px;flex:none;
  background:var(--primary)}

.n-top{display:inline-flex;align-items:center;gap:var(--s3);
  appearance:none;border:var(--rule) solid var(--black);cursor:pointer;
  background:var(--care);color:var(--black);text-decoration:none;
  padding:var(--s2) var(--s4);min-height:var(--tap-min);
  font:900 14px/1 var(--font);font-stretch:var(--wdth-condensed);
  text-transform:uppercase;letter-spacing:.04em;
  transition:transform var(--dur-bounce) var(--ease-verb-bounce)}
.n-top svg{width:20px;height:22px;flex:none}
.n-top svg path{fill:currentColor}
.n-top:hover,.n-top.is-hover{transform:translateY(calc(var(--s1) * -1))}
.n-top.is-focus{outline:var(--focus-width) solid var(--focus-colour);
  outline-offset:var(--focus-offset)}

/* the skip link. Off screen until focused, then a solid black bar at the top of
   whatever contains it, never a floating chip. */
.n-skip{position:absolute;left:var(--s4);top:var(--s4);z-index:var(--z-chrome);
  transform:translateY(-200%);
  display:inline-flex;align-items:center;min-height:var(--tap-min);
  padding:var(--s2) var(--s4);background:var(--black);color:var(--cream);
  text-decoration:none;
  font:900 14px/1 var(--font);font-stretch:var(--wdth-condensed);
  text-transform:uppercase;letter-spacing:.04em;
  transition:transform var(--dur-bounce) var(--ease-verb-bounce)}
.n-skip:focus,.n-skip:focus-visible,.n-skip.is-focus{transform:translateY(0);
  outline:var(--focus-width) solid var(--focus-colour-on-dark);
  outline-offset:var(--focus-offset)}

/* ----------------------------------------------------------------------------
   N9 , THE REPEAT-BANNER LOCKUP AS A SLOW MARQUEE
   The drawn repeat-banner artwork, run at 90 to 120s a loop. It is the artwork
   itself, not the wordmark re-typeset, so the marquee is the mark repeating and
   nothing has been redrawn.
   ---------------------------------------------------------------------------- */
.n-marquee{overflow:hidden;position:relative;
  border-top:var(--rule) solid var(--black);border-bottom:var(--rule) solid var(--black)}
.n-marquee__run{display:flex;width:max-content;
  animation:n-marquee var(--dur-marquee) var(--ease-linear) infinite}
.n-marquee__run u-svg{flex:0 0 auto;height:var(--banner-h,64px)}
.n-marquee__run u-svg svg{height:100%;width:auto}
@keyframes n-marquee{to{transform:translateX(-50%)}}
.n-marquee.is-paused .n-marquee__run{animation-play-state:paused}
@media (prefers-reduced-motion:reduce){
  .n-marquee__run{animation:none}
}

/* ----------------------------------------------------------------------------
   N10 , THE FOOTER
   Wordmark large, four link columns, the newsletter as a stub, the socials, a
   partner strip of placeholders, the legal row, and THE ONE PATTERN ON THIS PAGE
   as a single band at the very foot, through .pattern-slot with its edge fade,
   exactly as the set-times poster ends.
   ---------------------------------------------------------------------------- */
.n-foot{background:var(--black);color:var(--cream);
  --ground:var(--black);--ink:var(--cream);--focus-colour:var(--focus-colour-on-dark)}
.n-foot__top{padding:var(--s7) var(--s5) var(--s6);
  display:grid;gap:var(--s7);
  grid-template-columns:minmax(220px,1fr) minmax(0,1.6fr)}
.n-foot__mark{min-width:0}
.n-foot__mark u-svg{width:100%;max-width:340px}
.n-foot__mark path{fill:var(--cream)}
/* Louis's ruling, 20 Sep: no rotated or slanted type anywhere, and no drawn
   underline. The line under the mark is set STRAIGHT in the micro voice. */
.n-foot__line{display:block;margin-top:var(--s5);color:var(--yellow)}
.n-foot__cols{display:grid;gap:var(--s6) var(--s5);
  grid-template-columns:repeat(auto-fit,minmax(140px,1fr));align-content:start}
.n-foot__col h3{margin:0 0 var(--s3);font:700 var(--size-micro)/1.35 var(--font);
  letter-spacing:var(--track-micro);text-transform:uppercase;color:var(--yellow)}
.n-foot__col ul{margin:0;padding:0;list-style:none}
.n-foot__col li{margin-bottom:var(--s1)}
.n-foot__col a{display:inline-flex;align-items:center;min-height:38px;
  text-decoration:none;font-size:var(--size-small);
  border-bottom:var(--rule) solid transparent}
.n-foot__col a:hover,.n-foot__col a.is-hover{border-bottom-color:var(--primary)}

/* the newsletter. A stub, because signing up is taking a ticket: you tear off
   the tab and keep it. The device does the work; this only lays out the field. */
.n-foot__news{grid-column:1/-1;display:grid;gap:var(--s4);
  padding-top:var(--s6);border-top:var(--rule) solid var(--hairline-on-dark)}
.n-foot__news .d-stub{max-width:520px;background:var(--cream)}
.n-foot__field{display:flex;flex-wrap:wrap;gap:var(--s3);align-items:flex-end}
.n-foot__field label{display:block;font:700 var(--size-micro)/1.35 var(--font);
  letter-spacing:var(--track-micro);text-transform:uppercase;margin-bottom:var(--s2)}
.n-foot__field input{appearance:none;border:var(--rule-heavy) solid var(--black);
  background:var(--cream);color:var(--black);
  padding:var(--s3) var(--s4);min-height:var(--tap-min);width:min(300px,100%);
  border-radius:var(--radius-slab);font-size:var(--size-body)}
.n-foot__field input:focus-visible{outline:var(--focus-width) solid var(--focus-colour-on-dark);
  outline-offset:var(--focus-offset)}

.n-foot__social{display:flex;flex-wrap:wrap;gap:var(--s3);padding:0 var(--s5) var(--s6);
  margin:0;list-style:none}
.n-foot__social a{display:inline-flex;align-items:center;gap:var(--s2);
  min-height:var(--tap-min);padding:var(--s2) var(--s4);text-decoration:none;
  background:var(--cream);color:var(--black);
  font:900 14px/1 var(--font);font-stretch:var(--wdth-condensed);
  text-transform:uppercase;letter-spacing:.04em;
  transition:transform var(--dur-squash) var(--ease-verb-squash)}
.n-foot__social a:hover,.n-foot__social a.is-hover{transform:scale(1.04,.94)}

/* the partner strip. Placeholders, set as plain ruled boxes, because a partner's
   own mark is the only thing that goes here and we do not invent one. */
.n-foot__partners{padding:var(--s5);border-top:var(--rule) solid var(--hairline-on-dark)}
.n-foot__partners h3{margin:0 0 var(--s4);font:700 var(--size-micro)/1.35 var(--font);
  letter-spacing:var(--track-micro);text-transform:uppercase;color:var(--yellow)}
.n-foot__partners ul{margin:0;padding:0;list-style:none;
  display:grid;gap:var(--s3);grid-template-columns:repeat(auto-fit,minmax(150px,1fr))}
.n-foot__partners li{display:grid;place-items:center;min-height:72px;
  border:var(--rule) solid var(--hairline-on-dark);
  font:700 var(--size-micro)/1.35 var(--font);letter-spacing:var(--track-micro);
  text-transform:uppercase;opacity:.75;text-align:center;padding:var(--s3)}

.n-foot__legal{display:flex;flex-wrap:wrap;gap:var(--s3) var(--s5);align-items:center;
  justify-content:space-between;padding:var(--s4) var(--s5);
  border-top:var(--rule) solid var(--hairline-on-dark)}
.n-foot__legal ul{display:flex;flex-wrap:wrap;gap:var(--s4);margin:0;padding:0;list-style:none}
.n-foot__legal a{min-height:38px;display:inline-flex;align-items:center;text-decoration:none;
  border-bottom:var(--rule) solid transparent}
.n-foot__legal a:hover{border-bottom-color:var(--primary)}
.n-foot__legal li,.n-foot__legal p{font:700 var(--size-micro)/1.35 var(--font);
  letter-spacing:var(--track-micro);text-transform:uppercase;margin:0}

/* THE ONE PATTERN ON THIS PAGE. A single band at the very foot, through the
   shared .pattern-slot, so its edges fade into the ground rather than stopping
   on a guillotine, and so Louis's drawn artwork drops in with no rebuild.
   Nothing else on this page carries pattern. */
.n-foot__band{--pattern-height:104px;--pattern-fade:16%}

@media (max-width:760px){
  .n-foot__top{grid-template-columns:1fr;gap:var(--s6)}
  .n-foot__mark u-svg{max-width:260px}
}

/* ----------------------------------------------------------------------------
   Shared small parts used by more than one spec on this page.
   ---------------------------------------------------------------------------- */
/* the EN/ES switch is the SHARED .d-sticker--switch, used exactly as the planner
   fixed it (rounded outlined track, knob under one label). This lane adds
   nothing but the flex behaviour it needs to sit in a row. */
.n-lang{flex:none}
/* A blade shown LOOSE, outside a post, in a state cell or the parts bin. It keeps
   its shape, its colour and its swing, but it must not carry the post-relative
   offsets: at 390 the left-pointer's flex-end alignment pushed it 4px past the
   viewport. Loose blades align to the start and size themselves to the cell. */
.spec-states__cell > .n-blade,.n-parts > .spec-states__cell > .n-blade{
  align-self:flex-start;margin-left:0;margin-right:0;max-width:100%}

/* the parts bin. A wrapping row of loose assets, each in its own labelled cell.
   Every cell CLIPS, because a part shown loose (the pattern band, the marquee
   lockup) is as wide as its own artwork and would otherwise drag the whole spec
   past the viewport, which is what the first render did by 17,672px. */
.n-parts{display:flex;flex-wrap:wrap;gap:var(--s5);align-items:flex-start;min-width:0}
.n-parts > .spec-states__cell{min-width:0;max-width:100%;overflow:hidden}
.n-parts > .spec-states__cell > .t-micro{opacity:.6}

/* a stacked row of specimens inside one stage */
.n-stack{display:grid;gap:var(--s6)}
.n-note{font:700 var(--size-micro)/1.35 var(--font);letter-spacing:var(--track-micro);
  text-transform:uppercase;opacity:.6;margin:0}

/* PLANNER, 20 Sep: in Louis's N3 the menu button sits HARD RIGHT of the phone header, the
   wordmark left. It was sitting beside the wordmark. */
.n-frame--phone .n-head{display:flex;align-items:center;justify-content:space-between}
.n-frame--phone .n-head__burger{margin-left:auto}
