/* ============================================================
   FLIPBOARD · SPLIT-FLAP ARRIVALS BOARD
   Styles for assets/js/flipboard.js, which builds the markup.
   Reads the site tokens (--ink-2, --gold, --cream ...) and falls
   back to the same values, so it also works on its own.
   One tile width, --fb-tw, drives every size on the board.
   ============================================================ */

.fb{
  /* palette */
  --fb-tile-hi:   #142735;
  --fb-tile-top:  var(--ink-3, #11202c);
  --fb-tile-bot:  var(--ink-2, #0c1822);
  --fb-tile-lo:   #09141c;
  --fb-char:      var(--cream, #f4ece0);
  --fb-gold:      var(--gold, #c9a35e);
  --fb-gold-soft: var(--gold-soft, #e3c488);
  --fb-gold-dim:  var(--gold-dim, rgba(201,163,94,.34));
  --fb-gold-faint:var(--gold-faint, rgba(201,163,94,.14));
  --fb-amber:     #f2ad4c;
  --fb-font:      var(--sans, "Jost", system-ui, sans-serif);
  --fb-serif:     var(--serif, "Cormorant Garamond", Georgia, serif);
  --fb-ease:      var(--ease, cubic-bezier(.22,.61,.36,1));

  /* sizing. --fb-u (tile widths across the board) comes from the
     small per-board stylesheet the script writes, one value per
     width band. --fb-min / --fb-max can be overridden per page. */
  --fb-min:   7px;
  --fb-max:   30px;
  --fb-pad:   0px;
  --fb-slack: 8px;
  --fb-avail: calc(100vw - 2rem);
  --fb-tw0: clamp(var(--fb-min),
                  calc((var(--fb-avail) - 2 * var(--fb-pad) - var(--fb-slack)) / var(--fb-u, 40)),
                  var(--fb-max));
  --fb-tw: var(--fb-tw0);

  container-type:inline-size;
  display:block;
  width:100%;
}
@supports (width:1cqi){
  .fb{ --fb-avail:100cqi; }
}

.fb__board{
  position:relative;
  width:fit-content;
  max-width:100%;
  margin-inline:auto;
}

/* ---------- optional housing ---------- */

/* Only with { frame:true }. Inside an existing card, leave it off. */
.fb--framed{ --fb-pad:clamp(.6rem, 2.4vw, 1.9rem); }
.fb--framed .fb__board{
  padding:var(--fb-pad);
  background:
    radial-gradient(120% 80% at 50% -20%, rgba(141,182,169,.07), transparent 60%),
    linear-gradient(180deg, #0a1620, #060e14);
  border:1px solid var(--fb-gold-dim);
  box-shadow:
    0 50px 100px -50px rgba(0,0,0,.9),
    inset 0 1px 0 rgba(244,236,224,.04);
}
/* thin double gold frame, like the printed card */
.fb--framed .fb__board::after{
  content:"";
  position:absolute;
  inset:calc(var(--fb-pad) * .38);
  border:1px solid var(--fb-gold-faint);
  pointer-events:none;
}

/* ---------- top bar: title and clock ---------- */

/* width:0 + min-width:100% lets it fill the board without ever
   widening it, so the tile maths alone decides the width. */
.fb__top{
  display:flex;
  align-items:center;
  justify-content:space-between;
  gap:1rem;
  width:0;
  min-width:100%;
  padding-bottom:calc(var(--fb-tw) * .8);
}
.fb__title{
  margin:0;
  min-width:0;
  font-family:var(--fb-serif);
  font-style:italic;
  font-weight:400;
  font-size:clamp(1.15rem, calc(var(--fb-tw) * 1.2), 1.9rem);
  line-height:1.2;
  letter-spacing:.01em;
  color:var(--fb-gold-soft);
  white-space:nowrap;
  overflow:hidden;
  text-overflow:ellipsis;
  padding-right:.15em; /* room for the italic overhang */
}
.fb__clock{
  --fb-tw:calc(var(--fb-tw0) * .8);
  display:flex;
  align-items:center;
  gap:calc(var(--fb-tw) * var(--fb-tg));
  flex:none;
  margin-left:auto;
}
.fb__clock-name{
  font-family:var(--fb-font);
  font-weight:400;
  font-size:clamp(.56rem, calc(var(--fb-tw0) * .5), .72rem);
  line-height:1;
  letter-spacing:.3em;
  text-transform:uppercase;
  color:var(--fb-gold);
  margin-right:.8em;
}
.fb__colon{
  width:calc(var(--fb-tw) * .45);
  text-align:center;
  font-family:var(--fb-font);
  font-weight:400;
  font-size:calc(var(--fb-tw) * .9);
  line-height:1;
  color:var(--fb-gold);
}

/* ============================================================
   TABLE
   ============================================================ */

.fb__table{
  border-collapse:separate;
  border-spacing:0;
  margin:0;
}
.fb__table th,
.fb__table td{
  padding:0 calc(var(--fb-tw) * var(--fb-cg)) 0 0; /* column gap */
  vertical-align:top;
  text-align:left;
  font-weight:inherit;
}
.fb__table .fb__lc{
  padding:0;
  width:calc(var(--fb-tw) * var(--fb-lw));
}

/* ---------- header row ---------- */

.fb__table thead th{
  vertical-align:bottom;
  padding-bottom:calc(var(--fb-tw) * .55);
  border-bottom:1px solid var(--fb-gold-dim);
}

/* Zero width, so a long label never widens its column. It simply
   runs on into the gap, or leftwards for a right-aligned column. */
.fb__lbl{
  display:flex;
  width:0;
  white-space:nowrap;
  font-family:var(--fb-font);
  font-weight:400;
  font-size:clamp(.56rem, calc(var(--fb-tw) * .5), .72rem);
  line-height:1;
  letter-spacing:.3em;
  text-transform:uppercase;
  color:var(--fb-gold);
}
.fb__table th.is-right  .fb__lbl{ margin-left:auto; justify-content:flex-end; }
.fb__table th.is-right  .fb__lbl > span{ margin-right:-.3em; } /* trailing tracking */
.fb__table th.is-center .fb__lbl{ margin-inline:auto; justify-content:center; }

/* ---------- rows ---------- */

.fb__table tbody td{
  padding-top:calc(var(--fb-tw) * .34);
  padding-bottom:calc(var(--fb-tw) * .34);
}
.fb__table tbody tr:first-child td{ padding-top:calc(var(--fb-tw) * .8); }
.fb__table tbody tr + tr td{ border-top:1px solid rgba(244,236,224,.045); }

/* a cell: one line of tiles, or several when wrapped on narrow screens */
.fb__v{
  display:flex;
  flex-direction:column;
  gap:calc(var(--fb-tw) * var(--fb-lg));
}
.fb__v--n{ display:none; }
.fb__line{
  display:flex;
  gap:calc(var(--fb-tw) * var(--fb-tg));
}

/* ============================================================
   TILE
   At rest a tile shows one whole character over a two-tone card.
   While it changes, four half-height pieces take over:
     static top    new face        static bottom   old face
     top flap      old face, hinged at the split, falls forward
     bottom flap   new face, drops from the split and lands
   ============================================================ */

.fb__t{
  --fb-th:calc(var(--fb-tw) * 1.5);
  --fb-r:max(1px, calc(var(--fb-tw) * .1));
  --fb-nudge:-.05em; /* lifts mid crossbars (H, E, F) just clear of the split */
  position:relative;
  display:block;
  flex:none;
  width:var(--fb-tw);
  height:var(--fb-th);
  border-radius:var(--fb-r);
  perspective:calc(var(--fb-tw) * 6);
  contain:layout paint style;
  background:linear-gradient(180deg,
    var(--fb-tile-hi) 0, var(--fb-tile-top) 50%,
    var(--fb-tile-bot) 50%, var(--fb-tile-lo) 100%);
  font-family:var(--fb-font);
  font-weight:460;
  font-size:calc(var(--fb-tw) * .96);
  line-height:1;
  font-variant-numeric:tabular-nums;
  color:var(--fb-char);
  box-shadow:
    inset 0 1px 0 rgba(244,236,224,.06),
    0 1px 0 rgba(0,0,0,.7),
    0 calc(var(--fb-tw) * .12) calc(var(--fb-tw) * .3) -1px rgba(0,0,0,.55);
}

/* Even pixel heights put the split on a pixel edge, so it stays one
   crisp line instead of smearing across two rows. */
@supports (height:round(1.5px, 2px)){
  .fb__t{ --fb-th:max(10px, round(calc(var(--fb-tw) * 1.5), 2px)); }
}

/* the character: a full-height box, centred */
.fb__face,
.fb__h > b,
.fb__f > b{
  position:absolute;
  left:0; right:0;
  height:var(--fb-th);
  display:flex;
  align-items:center;
  justify-content:center;
  font:inherit;
  text-shadow:0 1px 0 rgba(0,0,0,.35);
  transform:translateY(var(--fb-nudge));
}
.fb__face{ top:0; }

/* Where supported, centre on the capital height itself rather than
   on the font's line box, so a fallback font sits where Jost does. */
@supports (text-box:trim-both cap alphabetic){
  .fb__face,
  .fb__h > b,
  .fb__f > b{
    display:block;
    text-align:center;
    text-box:trim-both cap alphabetic;
    padding-top:calc(var(--fb-th) / 2 - .5cap);
  }
}

/* the four pieces */
.fb__h,
.fb__f{
  position:absolute;
  left:0; right:0;
  height:50%;
  overflow:hidden;
  visibility:hidden;
}
.fb__h{ z-index:1; }
.fb__f{
  z-index:2;
  -webkit-backface-visibility:hidden;
  backface-visibility:hidden;
}
.fb__t.is-flip .fb__h,
.fb__t.is-flip .fb__f{ visibility:visible; }
.fb__t.is-flip .fb__f{ will-change:transform; }

.fb__h--t,
.fb__f--t{
  top:0;
  border-radius:var(--fb-r) var(--fb-r) 0 0;
  background:linear-gradient(180deg, var(--fb-tile-hi), var(--fb-tile-top));
  box-shadow:inset 0 1px 0 rgba(244,236,224,.06);
  transform-origin:50% 100%;
}
.fb__h--b,
.fb__f--b{
  bottom:0;
  border-radius:0 0 var(--fb-r) var(--fb-r);
  background:linear-gradient(180deg, var(--fb-tile-bot), var(--fb-tile-lo));
  transform-origin:50% 0;
}
.fb__h--t > b, .fb__f--t > b{ top:0; }
.fb__h--b > b, .fb__f--b > b{ top:-100%; }

/* The hairline split across every tile. Not fully opaque, so it
   reads as a seam in the card, not a cut through the letter. */
.fb__t::after{
  content:"";
  position:absolute;
  z-index:3;
  left:0; right:0;
  top:calc(50% - .5px);
  height:1px;
  background:rgba(2,6,9,.62);
  box-shadow:0 1px 0 rgba(244,236,224,.04);
}
/* and the two hinge pins at its ends */
.fb__t::before{
  --pin:max(1px, calc(var(--fb-tw) * .07));
  content:"";
  position:absolute;
  z-index:4;
  left:0; right:0;
  top:calc(50% - var(--pin));
  height:calc(var(--pin) * 2);
  background:linear-gradient(90deg,
    #02070a 0 var(--pin),
    transparent var(--pin) calc(100% - var(--pin)),
    #02070a calc(100% - var(--pin)));
}

/* ============================================================
   STATUS LAMP
   Dark until its row has landed, then it lights with a flicker.
   ============================================================ */

.fb__lamp{
  --fb-ls:max(6px, calc(var(--fb-tw) * .4));
  position:relative;
  display:block;
  width:var(--fb-ls);
  height:var(--fb-ls);
  margin:calc(var(--fb-tw) * .75 - var(--fb-ls) / 2) 0 0 auto;
  border-radius:50%;
  background:radial-gradient(circle at 35% 30%, #3d3121, #19130b 75%);
  box-shadow:inset 0 0 0 1px rgba(0,0,0,.55), 0 1px 0 rgba(244,236,224,.05);
}
.fb__lamp::after{
  content:"";
  position:absolute;
  inset:0;
  border-radius:50%;
  background:radial-gradient(circle at 36% 30%, #fff4d6 0, #ffd58a 26%, var(--fb-amber) 60%, #a8651c 100%);
  box-shadow:
    0 0 max(5px, calc(var(--fb-ls) * .9)) rgba(242,173,76,.8),
    0 0 max(12px, calc(var(--fb-ls) * 2.6)) rgba(242,173,76,.3);
  opacity:0;
  transition:opacity .45s var(--fb-ease);
}
.fb__lamp.is-on::after{ opacity:1; }
.fb__lamp.is-ignite::after{ animation:fb-ignite .7s linear both; }

@keyframes fb-ignite{
  0%  { opacity:0; }
  14% { opacity:1; }
  26% { opacity:.3; }
  40% { opacity:1; }
  55% { opacity:.7; }
  100%{ opacity:1; }
}

/* ---------- screen-reader text ---------- */

.fb-sr{
  position:absolute !important;
  width:1px; height:1px;
  padding:0; margin:-1px;
  overflow:hidden;
  clip:rect(0 0 0 0);
  clip-path:inset(50%);
  white-space:nowrap;
  border:0;
}

/* ---------- reduced motion and forced colours ---------- */

@media (prefers-reduced-motion:reduce){
  .fb__lamp::after{ transition:none; }
  .fb__lamp.is-ignite::after{ animation:none; }
}

@media (forced-colors:active){
  .fb__t{ outline:1px solid CanvasText; }
  .fb__t::before, .fb__t::after{ display:none; }
}
