/* CHA Star Holdings -- the one page.
 *
 * No color literal lives here. Every color is a var() from tokens.css.
 * Fonts are self-hosted from /assets/fonts/. The page makes zero network
 * requests: nothing here points off this machine.
 */

/* ---- type ------------------------------------------------------------- */

@font-face {
  font-family: "League Spartan";
  src: url("/assets/fonts/league-spartan-700-latin.woff2") format("woff2");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Overpass";
  src: url("/assets/fonts/overpass-wght-latin.woff2") format("woff2");
  font-weight: 400 700;
  font-style: normal;
  font-display: swap;
}

/* ---- reset ------------------------------------------------------------ */

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
}

body {
  margin: 0;
  min-height: 100vh;
  background: var(--stage);
  background-repeat: no-repeat;
  background-attachment: fixed;
  color: var(--white);
  font-family: var(--font-body);
  font-size: var(--size-body);
  line-height: var(--line-body);
  -webkit-font-smoothing: antialiased;
}

h1,
h2,
p,
ul {
  margin: 0;
}

ul {
  padding: 0;
  list-style: none;
}

img {
  display: block;
}

a {
  color: var(--sky);
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.wrap {
  width: 100%;
  max-width: var(--content-max);
  margin: 0 auto;
  padding: 0 var(--space-3);
}

:focus-visible {
  outline: var(--focus-width) solid var(--sky);
  outline-offset: 2px;
}

/* ---- the sky pill, the only button shape on the page ------------------ */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-1);
  padding: 10px var(--space-3);
  border: 0;
  border-radius: var(--radius-button);
  background: var(--sky);
  color: var(--navy);
  font-family: var(--font-body);
  font-size: var(--size-body);
  font-weight: 700;
  line-height: 1.2;
  text-decoration: none;
  transition: transform var(--dur-hover) ease, filter var(--dur-hover) ease;
}

.btn:hover {
  transform: translateY(var(--lift-distance));
  filter: brightness(1.06);
}

.btn-sm {
  padding: 7px var(--space-2);
  font-size: var(--size-small);
}

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

.site-header {
  position: sticky;
  top: 0;
  z-index: 10;
  height: var(--header-height);
  background: var(--header-glass);
  -webkit-backdrop-filter: blur(var(--header-blur)) saturate(var(--header-saturate));
  backdrop-filter: blur(var(--header-blur)) saturate(var(--header-saturate));
  border-bottom: 1px solid transparent;
  transition: border-color var(--dur-hover) ease,
    background-color var(--dur-hover) ease;
}

/* Something is under the bar now: deepen the tint and draw the hairline. */
.site-header.is-stuck {
  background: var(--header-glass-stuck);
  border-bottom-color: var(--hairline);
}

/* No backdrop-filter means no blur, and a 30%-alpha bar over a moving card
   is then just a smudge you can read the card through. Those browsers get
   the solid bar this header had before. Checked as two separate features
   because Safari shipped the prefixed one years before the plain one. */
@supports not ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) {
  .site-header,
  .site-header.is-stuck {
    background: var(--midnight);
  }
}

.header-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  height: 100%;
  /* The anchor the popover hangs off. Nothing else about this row changes:
     the menu button was put inside .header-controls beside the call to
     action precisely so the row's own spacing did not have to move. */
  position: relative;
}

.logo-link {
  display: inline-flex;
  align-items: center;
}

.logo-link img {
  height: 44px;
  width: auto;
}

/* ---- the menu button and its popover ---------------------------------- */

/* The button and the call to action travel together on the right, so the
   row still has exactly two children and its spacing is untouched. */
.header-controls {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
}

.menu-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  min-width: 44px;
  min-height: 44px;
  padding: 0;
  border: 0;
  border-radius: var(--radius-button);
  background: transparent;
  color: var(--white);
  cursor: pointer;
}

.menu-btn:hover {
  background: var(--menu-hover);
}

.menu-bars {
  position: relative;
  display: block;
  width: 20px;
  height: 14px;
}

/* Three bars that become an X, and back, as ONE movement rather than two
   icons swapped. The delays below are what does that, and they are not
   symmetrical on purpose: see the pair of rules under .menu-open. */
.menu-bar {
  position: absolute;
  left: 0;
  width: 20px;
  height: 2px;
  border-radius: var(--radius-pill);
  background: currentColor;
  transition: transform var(--dur-menu) var(--ease-flip),
    opacity var(--dur-menu) var(--ease-flip);
}

.menu-bar:nth-child(1) { top: 0; }
.menu-bar:nth-child(2) { top: 6px; transition-delay: var(--menu-stagger); }
.menu-bar:nth-child(3) { top: 12px; }

/* Each bar carries the delay it uses on the way IN here, and the delay it
   uses on the way OUT in the rules above. Opening, the middle bar's delay is
   0 and the outer two wait: the X clears its own centre before it closes.
   Closing, the declarations above apply instead, so the outer two sweep back
   first and the middle bar arrives last to finish the shape. */
.site-header.menu-open .menu-bar:nth-child(1) {
  transform: translateY(6px) rotate(45deg);
  transition-delay: var(--menu-stagger);
}

.site-header.menu-open .menu-bar:nth-child(2) {
  opacity: 0;
  transform: scaleX(0.2);
  transition-delay: 0ms;
}

.site-header.menu-open .menu-bar:nth-child(3) {
  transform: translateY(-6px) rotate(-45deg);
  transition-delay: var(--menu-stagger);
}

/* A SMALL PANEL HANGING OFF THE BUTTON. Absolutely positioned inside the
   header row, never fixed: a fixed panel is how a popover turns into the
   full-screen overlay this page does not have. Its height is capped at what
   is left of the short viewport under the bar and it scrolls inside that,
   so it can never run off the bottom of a phone. */
.menu-pop {
  position: absolute;
  top: calc(100% + var(--space-1));
  right: var(--space-3);
  width: min(300px, calc(100% - var(--space-3) * 2));
  max-height: calc(100svh - var(--header-height) - var(--space-4));
  overflow-y: auto;
  padding: var(--space-2);
  border: 1px solid var(--menu-line);
  border-radius: var(--radius-card);
  background: var(--menu-fill);
  -webkit-backdrop-filter: blur(var(--header-blur)) saturate(var(--header-saturate));
  backdrop-filter: blur(var(--header-blur)) saturate(var(--header-saturate));
  box-shadow: 0 var(--card-lift-y) var(--card-lift-blur) var(--menu-shadow);
  transform-origin: top right;
  opacity: 0;
  visibility: hidden;
  transform: translateY(-6px) scale(0.98);
  /* visibility is not animatable, so it is stepped at the far end of the
     fade OUT and immediately on the way IN. That is what keeps a panel that
     is still fading from sitting over the page and eating the pointer. */
  transition: opacity var(--dur-menu) var(--ease-flip),
    transform var(--dur-menu) var(--ease-flip),
    visibility 0s linear var(--dur-menu);
}

.site-header.menu-open .menu-pop {
  opacity: 1;
  visibility: visible;
  transform: none;
  transition: opacity var(--dur-menu) var(--ease-flip),
    transform var(--dur-menu) var(--ease-flip),
    visibility 0s;
}

/* Same reasoning as the header's own guard above: with no blur behind it a
   92%-alpha panel is still a smudge you can read the deck through, so those
   browsers get the solid bar colour instead. */
@supports not ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) {
  .menu-pop {
    background: var(--midnight);
  }
}

/* Text only. A reserved spot for something later, not a preview of one. */
.menu-welcome {
  padding-bottom: var(--space-2);
  margin-bottom: var(--space-2);
  border-bottom: 1px solid var(--menu-line);
}

.menu-welcome-title {
  font-family: var(--font-display);
  font-size: var(--size-name);
  line-height: var(--line-name);
  color: var(--white);
}

.menu-welcome-line {
  font-size: var(--size-small);
  line-height: var(--line-small);
  color: var(--haze);
  margin-top: 4px;
}

.menu-nav {
  display: grid;
  gap: 2px;
}

/* Buttons, not links: they drive the deck on this page. There is nowhere
   else to go yet. */
.menu-link {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  width: 100%;
  min-height: 44px;
  padding: 0 var(--space-1);
  border: 0;
  border-radius: var(--radius-button);
  background: transparent;
  color: var(--white);
  font-family: var(--font-body);
  font-size: var(--size-body);
  font-weight: 700;
  text-align: left;
  cursor: pointer;
  transition: background var(--dur-hover) ease;
}

.menu-link:hover {
  background: var(--menu-hover);
}

.menu-link-num {
  font-family: var(--font-display);
  font-size: var(--size-small);
  color: var(--sky);
  min-width: 22px;
}

/* A 1px sentinel at the very top of the document: when it leaves the viewport
   the header has something scrolled beneath it. Observed, never polled --
   there is no scroll listener on this page. */
.scroll-sentinel {
  position: absolute;
  top: 0;
  left: 0;
  width: 1px;
  height: 1px;
  pointer-events: none;
}

/* ======================================================================= */
/* THE DECK                                                                */
/*                                                                         */
/* Five cards on one rail. The rail is a native horizontal scroller with    */
/* snap points, so a trackpad and a thumb both get the browser's own        */
/* momentum for free -- no scroll listener, no hand-written physics. An     */
/* IntersectionObserver watching a thin band down the middle of the rail is */
/* the only thing that decides which card is at the front.                  */
/*                                                                         */
/* A card is two faces on one 3D box. Front is the resting state; the back  */
/* is the detail, reached by turning the card over.                        */
/* ======================================================================= */

/* The deck owns the fold. Everything between the bar and the bottom edge of
   the window is the deck's, so the footer starts one pixel below the fold and
   is only ever reached by scrolling. svh, not vh: on a phone vh is the TALL
   viewport, measured with the browser's own chrome hidden, so a vh fold is
   taller than the window you are actually looking at and the footer's first
   line shows through under the deck. svh is the short one -- the height with
   the address bar down -- and a fold built from it is hidden in both states.
   The vh line above it is the fallback for anything that has not got svh. */
main {
  display: flex;
  min-height: calc(100vh - var(--header-height));
  min-height: calc(100svh - var(--header-height));
}

/* The section is the column inside that fold: rail on top, controls beneath,
   the pair centred in whatever height is left.
   (The class also stays on the section because cards.js hangs the deck's
   keyboard handling on it -- Escape closes a turned card -- so removing it
   from the markup silently kills the keyboard, and nothing errors.) */
.deck {
  display: flex;
  flex: 1;
  flex-direction: column;
  justify-content: center;
  min-width: 0;
}

.deck-track {
  display: flex;
  gap: var(--deck-gap);
  /* Half a viewport of lead-in and run-out, so the first and last card can
     each reach the middle. What is left over beside the front card is
     exactly how much of its neighbours you see. */
  padding-inline: max(var(--space-3), calc(50% - var(--deck-card-w) / 2));
  /* Room above and below for a card at full size and its shadow. The rail
     clips whatever it cannot fit, in a hard straight line right across the
     page, so this padding is the only thing keeping the shadow whole. It is
     derived from the shadow itself -- see --card-lift-y in tokens.css. */
  padding-block: var(--deck-clear-top) var(--deck-clear-bottom);
  /* Takes whatever height the fold has left over and hands it to the cards,
     which are sized from the rail rather than from the window. The floor is
     one card at its smallest plus the room its shadow needs on both sides:
     below that the page simply gets taller and scrolls, because a card
     squeezed under its own copy is worse than a scrollbar. */
  flex: 1 1 auto;
  min-height: calc(
    var(--deck-card-h) + var(--deck-clear-top) + var(--deck-clear-bottom)
  );
  overflow-x: auto;
  overflow-y: hidden;
  scroll-snap-type: x mandatory;
  overscroll-behavior-x: contain;
  scrollbar-width: none;
}

.deck-track::-webkit-scrollbar {
  display: none;
}

/* The wrap. The rail is faded, not hidden: visibility and display would
   stop the IntersectionObserver reporting anything, and the observer is
   how this deck knows which card is at the front. Opacity does not. */
.deck-track {
  transition: opacity var(--dur-wrap-in) ease-out;
}

.deck.is-wrapping .deck-track {
  opacity: var(--wrap-dim);
  transition: opacity var(--dur-wrap-out) ease-in;
}

.deck-slot {
  flex: 0 0 var(--deck-card-w);
  /* Full height of the rail, up to a ceiling: on a short window the card
     shrinks to fit the fold, on a tall one it stops growing and centres in
     what is left, because past that ceiling a card stops reading as a card
     and starts reading as a column. */
  height: 100%;
  max-height: var(--deck-card-max);
  align-self: center;
  scroll-snap-align: center;
  /* Per-card vanishing point: every card turns on its own axis, not on one
     shared with a card half a screen away. */
  perspective: var(--deck-perspective);
  animation: card-enter var(--dur-enter) ease-out backwards;
}

.deck-slot:nth-child(1) { animation-delay: calc(0 * var(--stagger-step)); }
.deck-slot:nth-child(2) { animation-delay: calc(1 * var(--stagger-step)); }
.deck-slot:nth-child(3) { animation-delay: calc(2 * var(--stagger-step)); }
.deck-slot:nth-child(4) { animation-delay: calc(3 * var(--stagger-step)); }
.deck-slot:nth-child(5) { animation-delay: calc(4 * var(--stagger-step)); }

@keyframes card-enter {
  from {
    opacity: 0;
    transform: translateY(var(--enter-distance));
  }
  to {
    opacity: 1;
    transform: none;
  }
}

/* ---- the card as a 3D box --------------------------------------------- */

.deck-card {
  position: relative;
  /* The slot stretches to the full height of the rail's content box and the
     card fills the slot, so the deck is as tall as the fold allows. */
  height: 100%;
  transform-style: preserve-3d;
  /* At rest a card sits back from the front one. */
  transform: scale(var(--deck-rest-scale));
  opacity: var(--deck-rest-opacity);
  transition: transform var(--dur-flip) var(--ease-flip),
    opacity var(--dur-slide) ease;
}

.deck-slot.is-current .deck-card {
  transform: scale(1);
  opacity: 1;
}

/* The 180. Only ever applied to the card at the front. */
.deck-slot.is-current .deck-card.is-turned {
  transform: scale(1) rotateY(180deg);
}

.face {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  padding: var(--space-3);
  border: 1px solid var(--card-line);
  border-top-width: 2px;
  border-radius: var(--radius-card);
  background: var(--card-fill);
  box-shadow: 0 10px 24px var(--card-shadow);
  overflow: hidden;
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
  transition: background-color var(--dur-hover) ease,
    border-color var(--dur-hover) ease,
    box-shadow var(--dur-slide) ease;
}

.face-back {
  transform: rotateY(180deg);
  background: var(--face-back-fill);
}

.deck-slot.is-current .face {
  border-color: var(--card-line-hover);
  box-shadow: 0 var(--card-lift-y) var(--card-lift-blur) var(--card-shadow-lift);
}

/* A --sky bloom, clipped to the card, on the front card only. It is the one
   thing that says "this one" without adding a second accent.
   The box is far bigger than the card so the falloff is still gentle where
   the card clips it, and the stops ease out rather than running to the edge
   of the ellipse at a constant rate. See --glow in tokens.css for why the
   last stop is not `transparent`. */
.deck-slot.is-current .face::before {
  content: "";
  position: absolute;
  top: -70%;
  left: -50%;
  width: 170%;
  height: 170%;
  background: radial-gradient(
    closest-side,
    var(--glow) 0%,
    var(--glow-soft) 38%,
    var(--glow-faint) 66%,
    var(--glow-fade) 100%
  );
  pointer-events: none;
}

.deck-slot.is-current .face-front:hover {
  background-color: var(--card-fill-hover);
}

/* ---- the front face: a poster ----------------------------------------- */

/* The whole resting face is the control. It is laid over the face at full
   size and painted above the copy, so a click anywhere lands on a real
   button; the heading stays outside it so the markup stays valid. */
.face-hit {
  position: absolute;
  inset: 0;
  width: 100%;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
}

.face-hit:focus-visible {
  outline: none;
}

.deck-card:has(.face-hit:focus-visible) .face-front {
  outline: var(--focus-width) solid var(--sky);
  outline-offset: 2px;
}

.card-index {
  position: absolute;
  top: var(--space-3);
  right: var(--space-3);
  color: var(--haze);
  font-family: var(--font-display);
  font-size: var(--size-small);
  font-weight: 700;
  letter-spacing: 0.16em;
  opacity: 0.55;
  pointer-events: none;
}

.card-tag {
  padding-right: var(--space-4);
  color: var(--haze);
  font-size: var(--size-small);
  line-height: var(--line-small);
  letter-spacing: var(--tracking-tag);
  text-transform: uppercase;
}

/* Everything else on the front face is pushed to the foot of the card. */
.card-name-row {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-1) var(--space-2);
  margin-top: auto;
}

.card-name {
  font-family: var(--font-display);
  font-size: var(--size-display);
  font-weight: 700;
  line-height: var(--line-display);
  letter-spacing: 0.005em;
}

.badge {
  padding: 2px 10px;
  border: 1px solid var(--sky);
  border-radius: var(--radius-pill);
  color: var(--sky);
  font-size: 11px;
  line-height: 1.5;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  white-space: nowrap;
}

.card-line {
  max-width: 34ch;
  margin-top: var(--space-2);
  color: var(--haze);
  font-size: var(--size-lede);
  line-height: var(--line-lede);
}

/* The invitation to turn the card. It belongs to the front card alone --
   on a card at rest it would be an instruction you cannot follow yet. */
.card-cue {
  display: inline-flex;
  align-items: center;
  align-self: flex-start;
  gap: 6px;
  /* The second of the two auto margins on this face. Between them they split
     whatever height is left over, so the name lands mid-card and the cue
     lands on the floor -- the tall card reads as composed, not as a short
     card with a hole under the tag. */
  margin-top: auto;
  padding-top: var(--space-3);
  color: var(--sky);
  font-size: var(--size-small);
  line-height: var(--line-small);
  font-weight: 700;
  letter-spacing: var(--tracking-tag);
  text-transform: uppercase;
  opacity: 0;
  transition: opacity var(--dur-slide) ease, transform var(--dur-hover) ease;
}

.deck-slot.is-current .card-cue {
  opacity: 1;
}

.cue-chev {
  width: 14px;
  height: 14px;
  flex: none;
  transition: transform var(--dur-hover) ease;
}

.deck-slot.is-current .face-front:hover .cue-chev {
  transform: translateX(4px);
}

/* ---- the back face: the detail ---------------------------------------- */

/* Nothing is drawn on the card to close it: a click anywhere on the detail
   that is not a link or a button turns the card back, the same way a click
   anywhere on the front turned it over.
   This button is here for the keyboard and for screen readers, and it is
   drawn only once a keyboard has reached it -- the trick a skip link uses.
   A pointer never sees it; a Tab key always can. */
.face-close {
  position: absolute;
  top: var(--space-2);
  right: var(--space-2);
  z-index: 2;
  width: 1px;
  height: 1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  border: 0;
  background: none;
  color: var(--haze);
  font-family: var(--font-body);
  font-size: var(--size-small);
  line-height: var(--line-small);
  white-space: nowrap;
}

.face-close:focus-visible {
  width: auto;
  height: auto;
  padding: 6px var(--space-2);
  overflow: visible;
  clip-path: none;
  border: 1px solid var(--card-line);
  border-radius: var(--radius-pill);
  background: var(--card-fill-hover);
  color: var(--white);
}

/* The whole reverse is the control, so it reads as one. */
.face-back {
  cursor: pointer;
}

/* A face is a focus target for the script alone (see cards.js). It is not in
   the tab order and it is never outlined -- it exists so that turning a card
   with the pointer keeps the reader's place without drawing anything. */
.face:focus {
  outline: none;
}

/* If a card is short and the copy is long, the detail scrolls inside the
   card rather than growing it: the deck keeps one height throughout. */
.face-scroll {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
  padding-right: var(--space-1);
  overflow-y: auto;
  scrollbar-width: thin;
}

.card-back-name {
  margin-top: 6px;
  font-family: var(--font-display);
  font-size: var(--size-name);
  font-weight: 700;
  line-height: var(--line-name);
  letter-spacing: 0.02em;
}

.card-para {
  max-width: var(--measure);
  margin-top: var(--space-2);
  color: var(--haze);
}

.card-note {
  margin-top: var(--space-2);
  color: var(--haze);
  font-size: var(--size-small);
  line-height: var(--line-small);
}

.card-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  /* Auto, so on a long card the buttons drop to the foot of the face and on
     a short one they simply follow the copy. */
  margin-top: auto;
  padding-top: var(--space-3);
}

.card-link {
  color: var(--sky);
  font-size: var(--size-small);
  line-height: var(--line-small);
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* ---- the rail's own controls ------------------------------------------ */

.deck-nav {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-3);
  padding-bottom: var(--space-6);
  /* The rail above leaves --deck-clear-bottom of empty air under the card so
     its shadow can finish inside the rail instead of being sliced off at the
     edge. That air is empty, so the controls are lifted back up through it
     and the spacing reads as it looks, not as the shadow demands. */
  margin-top: calc(var(--space-5) - var(--deck-clear-bottom));
  /* Lifted over the rail's own padding, so the row is transparent to the
     pointer: a thumb dragging in that strip still reaches the rail. Only the
     controls themselves take the pointer back. */
  pointer-events: none;
}

.deck-nav button {
  pointer-events: auto;
}

.nav-arrow {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  flex: none;
  padding: 0;
  border: 1px solid var(--card-line);
  border-radius: var(--radius-pill);
  background: var(--card-fill);
  color: var(--white);
  cursor: pointer;
  transition: background-color var(--dur-hover) ease,
    border-color var(--dur-hover) ease, opacity var(--dur-hover) ease;
}

.nav-arrow:hover:not(:disabled) {
  background-color: var(--card-fill-hover);
  border-color: var(--card-line-hover);
}

.nav-arrow:disabled {
  opacity: 0.28;
  cursor: default;
}

.nav-arrow svg {
  width: 18px;
  height: 18px;
}

.deck-dots {
  display: flex;
  align-items: center;
  gap: 2px;
}

.dot {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 28px;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
}

.dot::after {
  content: "";
  width: 7px;
  height: 7px;
  border-radius: var(--radius-pill);
  background: var(--card-line-hover);
  transition: width var(--dur-slide) var(--ease-flip),
    background-color var(--dur-slide) ease;
}

.dot:hover::after {
  background: var(--haze);
}

.dot[aria-current="true"] {
  width: 32px;
}

.dot[aria-current="true"]::after {
  width: 20px;
  background: var(--sky);
}

/* ---- footer ----------------------------------------------------------- */

.site-footer {
  border-top: 1px solid var(--hairline);
  padding: var(--space-5) 0 var(--space-6);
  color: var(--haze);
  font-size: var(--size-small);
  line-height: 1.6;
}

.footer-brands {
  display: flex;
  flex-wrap: wrap;
  gap: 6px var(--space-1);
  margin-top: var(--space-1);
  font-family: var(--font-display);
  font-weight: 700;
  letter-spacing: 0.04em;
}

.footer-brands li {
  display: flex;
  align-items: center;
  gap: var(--space-1);
  color: var(--white);
}

.footer-brands li::before {
  content: "\00b7";
  color: var(--haze);
}

.footer-brands a {
  color: var(--white);
  text-decoration: none;
}

.footer-brands a:hover {
  color: var(--sky);
  text-decoration: underline;
  text-underline-offset: 3px;
}

.footer-mail {
  margin-top: var(--space-2);
}

.footer-note {
  margin-top: 4px;
}

/* ---- the deck at each width ------------------------------------------- */

@media (min-width: 640px) {
  .face {
    padding: var(--space-4);
  }

  .card-index {
    top: var(--space-4);
    right: var(--space-4);
  }

  .face-close {
    top: var(--space-3);
    right: var(--space-3);
  }
}

/* With scripting off, index.html's <noscript> block flattens every card and
   lays both of its faces out in flow. */
