@charset "UTF-8";
/* =====================================================================
   COMPONENTS

   Buttons are the audited TrustDice primitives (flat coral fill, white
   label, 8px radius, no border, no shadow — audit §2 rows 3 and 4).
   Everything else in this file is the pachinko campaign layer: machine cards,
   the licence panel and the arcade fx.
   ===================================================================== */

/* ---------------------------------------------------------------------
   Buttons — TrustDice primitive
   --------------------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .4em;
  min-height: var(--cta-height);
  padding: 0 20px;
  border: 0;
  border-radius: var(--radius-sm);
  font-size: .95rem;
  font-weight: 700;
  line-height: 1.3;
  letter-spacing: .01em;
  text-align: center;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color .14s var(--ease), border-color .14s var(--ease), transform .1s var(--ease);
}

/* Registration / conversion. Flat fill: the two gradient tokens hold the same
   measured colour, so this renders exactly like the official button. */
.btn--primary {
  background-image: linear-gradient(180deg, var(--td-primary-start) 0%, var(--td-primary-end) 100%);
  background-color: var(--td-primary-start);
  color: var(--td-primary-text);
  box-shadow: none;
}
.btn--primary:hover { background-image: none; background-color: var(--td-primary-hover); }
.btn--primary:active { transform: translateY(1px); }

/* Outline — transparent fill + coral border at ~50%, as measured on ログイン. */
.btn--outline {
  background: transparent;
  color: var(--td-text-primary);
  border: 1px solid var(--td-secondary-border);
}
.btn--outline:hover {
  border-color: var(--td-primary-start);
  background: rgba(253, 113, 111, .1);
}

/* Sizes. 40px is the audited official height (used by the header CTA); xl is
   the LP size the three in-page registration CTAs use (audit §4.5). The
   low-emphasis `btn--link` variant and the intermediate `btn--lg` size were
   retired in Phase 5 — the page has one primary action and no text-link CTAs. */
.btn--sm { min-height: var(--cta-height);    min-width: 98px; padding: 0 18px; font-size: .82rem; }
.btn--xl { min-height: var(--cta-height-xl); padding: 0 32px; font-size: 1.08rem; }
.btn--block { display: flex; width: 100%; }

/* The in-page registration CTAs. Mobile: full-width and thumb-friendly.
   Desktop: a deliberate width instead of spanning the whole column.

   Phase 5.8K added `.howto__cta` to both lists. That is the entire mechanism by
   which the how-to button matches the other three — one selector in each rule,
   no duplicated width, height, padding, radius or font size anywhere. */
.hero__actions .btn--xl,
.lineup__actions .btn--xl,
.howto__cta .btn--xl,
.final-cta__action .btn--xl { width: 100%; }

@media (min-width: 600px) {
  .hero__actions .btn--xl,
  .lineup__actions .btn--xl,
  .howto__cta .btn--xl,
  .final-cta__action .btn--xl { width: auto; min-width: 288px; }
}

/* ---------------------------------------------------------------------
   Icon tile (選ばれる理由 card heads)
   --------------------------------------------------------------------- */
.icon-chip {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 52px;
  height: 52px;
  border-radius: var(--radius-md);
  background: linear-gradient(160deg, var(--td-surface-2), var(--td-bg-canvas));
  border: 1.5px solid rgba(255, 199, 44, .45);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .12);
}
.icon-chip img { width: 30px; height: 30px; }

/* ---------------------------------------------------------------------
   Accordion panel (FAQ + how-to)
   --------------------------------------------------------------------- */
.panel {
  display: grid;
  grid-template-rows: 0fr;
  visibility: hidden;
  transition: grid-template-rows .26s var(--ease), visibility 0s linear .26s;
}
.panel__inner { overflow: hidden; }
.is-open > .panel,
.is-open .panel {
  grid-template-rows: 1fr;
  visibility: visible;
  transition: grid-template-rows .26s var(--ease), visibility 0s linear 0s;
}

/* ---------------------------------------------------------------------
   Machine card — original pachinko component on audited shared tokens
   --------------------------------------------------------------------- */
.machine-card {
  position: relative;
  display: block;
  height: 100%;
  overflow: hidden;
  border-radius: var(--radius-md);
  border: 1px solid var(--td-border-subtle);
  background: var(--td-surface-1);
  box-shadow: var(--shadow-card);
  text-decoration: none;
  transition: transform .16s var(--ease), border-color .16s var(--ease);
}
.machine-card::after {                     /* pachinko gold trim */
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  border: 1px solid rgba(255, 199, 44, .32);
  pointer-events: none;
}
.machine-card:hover {
  transform: translateY(-3px);
  border-color: rgba(255, 199, 44, .6);
}

.machine-card__badge {
  position: absolute;
  z-index: 3;
  top: 8px;
  left: 8px;
  padding: 4px 10px;
  border-radius: 5px;
  font-size: .72rem;
  font-weight: 900;
  line-height: 1.4;
  color: #fff;
  box-shadow: 0 2px 0 rgba(0, 0, 0, .45);
}
.machine-card__badge--new { background: linear-gradient(180deg, #3ee3ff, #0090d0); color: #05202b; }
.machine-card__badge--hot { background: linear-gradient(180deg, #ff5b8f, #d5003f); }
.machine-card__badge--std { background: linear-gradient(180deg, #ffe08a, #e0a000); color: #3a2200; }

.machine-card__media {
  position: relative;
  aspect-ratio: 3 / 4;
  overflow: hidden;
  background: #1a0126;
}
.machine-card__media img { width: 100%; height: 100%; object-fit: cover; }

.machine-card__body {
  padding: 7px 9px 9px;
  border-top: 1px solid var(--td-border-subtle);
}
.machine-card__cat {
  display: inline-block;
  margin-bottom: 4px;
  padding: 2px 8px;
  border-radius: 4px;
  background: var(--td-surface-2);
  font-size: .68rem;
  font-weight: 700;
  color: #e6dcf0;
}
.machine-card__title {
  font-size: .92rem;
  font-weight: 900;
  line-height: 1.35;
  color: #fff;
}

/* ---------------------------------------------------------------------
   License / operation panel
   --------------------------------------------------------------------- */
.license {
  /* Phase 5.8H 28/34; Phase 5.8I 19/23. */
  padding: 19px 0 23px;
  background: var(--td-bg-canvas);
  border-top: 1px solid var(--td-border-subtle);
}
.license__inner {
  padding: 13px 12px 14px;
  border-radius: var(--radius-lg);
  background: var(--td-surface-1);
  border: 1px solid var(--td-border-subtle);
  box-shadow: var(--shadow-card);
}
.license__head {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding-bottom: 10px;
  margin-bottom: 10px;
  border-bottom: 1px solid var(--td-border-subtle);
}
.license__icon {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 46px;
  height: 46px;
  border-radius: var(--radius-md);
  background: var(--td-surface-2);
  border: 1px solid rgba(255, 199, 44, .4);
}
.license__icon img { width: 26px; height: 26px; }
.license__title {
  font-size: clamp(1.1rem, 4.4vw, 1.4rem);
  font-weight: 900;
  line-height: 1.4;
  color: var(--td-text-primary);
}
.license__scope {
  margin-top: 4px;
  font-size: .86rem;
  line-height: 1.6;
  /* Phase 5.4: `--td-text-secondary` measures 3.81:1 here — below the 4.5:1
     text-contrast minimum against this panel's `--td-surface-1` background.
     `--td-brand-accent-2` is an already-audited TrustDice token (5.5:1+ on
     every background this panel uses) rather than a newly invented colour. */
  color: var(--td-brand-accent-2);
}

.license__grid { display: grid; gap: 8px; }
.license__row {
  display: grid;
  gap: 2px;
  padding: 10px 12px;
  border-radius: var(--radius-sm);
  background: var(--td-bg-canvas);
  border: 1px solid var(--td-border-subtle);
}
.license__key {
  font-size: .74rem;
  font-weight: 700;
  color: var(--td-brand-accent-2);
}
.license__val {
  font-size: .95rem;
  font-weight: 700;
  line-height: 1.6;
  color: var(--td-text-primary);
}
.license__val--mono {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  letter-spacing: .02em;
}
.license__status {
  display: inline-block;
  padding: 2px 10px;
  border-radius: 999px;
  background: rgba(108, 255, 158, .14);
  border: 1px solid rgba(108, 255, 158, .45);
  color: #8dffb5;
  font-size: .85rem;
}
.license__cert {
  display: inline-flex;
  align-items: center;
  gap: .4em;
  min-height: 44px;
  margin-top: 11px;
  padding: 0 16px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--td-secondary-border);
  color: var(--td-text-primary);
  font-weight: 700;
  font-size: .9rem;
  text-decoration: none;
}
.license__cert::after {
  content: "";
  width: .55em;
  height: .55em;
  border-top: 2px solid currentColor;
  border-right: 2px solid currentColor;
  transform: translateY(-1px) rotate(45deg);
}
.license__cert:hover {
  border-color: var(--td-primary-start);
  background: rgba(253, 113, 111, .1);
}

@media (min-width: 600px) {
  .license__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (min-width: 1200px) {
  .license { padding: 44px 0 52px; }
  .license__inner { padding: 16px 16px 18px; }
  .license__grid { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; }
}

/* ---------------------------------------------------------------------
   Decorative fx layers — pachinko campaign layer
   --------------------------------------------------------------------- */
.fx { position: absolute; inset: 0; pointer-events: none; z-index: 0; }

.fx--burst::before {
  content: "";
  position: absolute;
  inset: -40% -30%;
  background: repeating-conic-gradient(from 0deg, rgba(255, 199, 44, .20) 0deg 5deg, transparent 5deg 16deg);
  -webkit-mask-image: radial-gradient(closest-side, transparent 6%, #000 30%, transparent 80%);
  mask-image: radial-gradient(closest-side, transparent 6%, #000 30%, transparent 80%);
  animation: fx-spin 90s linear infinite;
}
.fx--burst.fx--bright::before { background: repeating-conic-gradient(from 0deg, rgba(255, 224, 138, .34) 0deg 5deg, transparent 5deg 15deg); }
.fx--burst.fx--max::before    { background: repeating-conic-gradient(from 0deg, rgba(255, 224, 138, .42) 0deg 4deg, transparent 4deg 13deg); }
.fx--burst.fx--soft::before   { opacity: .55; }

.fx--balls {
  background-image:
    radial-gradient(circle at 34% 32%, rgba(255, 255, 255, .16) 0 12%, rgba(255, 255, 255, .04) 34%, transparent 46%),
    radial-gradient(circle at 66% 68%, rgba(255, 255, 255, .10) 0 10%, rgba(255, 255, 255, .03) 30%, transparent 42%);
  background-size: 74px 74px, 74px 74px;
  background-position: 0 0, 37px 37px;
  opacity: .5;
}
.fx--balls.fx--soft { opacity: .28; }

.fx--streaks {
  background-image: repeating-linear-gradient(118deg, rgba(255, 255, 255, .055) 0 2px, transparent 2px 12px);
  opacity: .8;
}
.fx--streaks.fx--soft { opacity: .4; }

.fx--sparkles::after {
  content: "";
  position: absolute;
  inset: 0;
  background-image:
    radial-gradient(2px 2px at 12% 22%, #fff, transparent 60%),
    radial-gradient(2px 2px at 82% 16%, var(--pachi-gold-light), transparent 60%),
    radial-gradient(1.6px 1.6px at 28% 78%, var(--pachi-cyan), transparent 60%),
    radial-gradient(2px 2px at 68% 86%, #fff, transparent 60%),
    radial-gradient(1.6px 1.6px at 46% 40%, var(--pachi-gold), transparent 60%);
  animation: fx-twinkle 3.8s ease-in-out infinite alternate;
}
.fx--sparkles-dense::after {
  background-image:
    radial-gradient(2px 2px at 8% 18%, #fff, transparent 60%),
    radial-gradient(2px 2px at 24% 62%, var(--pachi-gold-light), transparent 60%),
    radial-gradient(2px 2px at 42% 12%, var(--pachi-cyan), transparent 60%),
    radial-gradient(2px 2px at 58% 84%, #fff, transparent 60%),
    radial-gradient(2px 2px at 76% 34%, var(--pachi-gold), transparent 60%),
    radial-gradient(2px 2px at 90% 72%, #fff, transparent 60%);
}

@keyframes fx-spin    { to { transform: rotate(360deg); } }
@keyframes fx-twinkle { from { opacity: .35; } to { opacity: 1; } }

/* =====================================================================
   PHASE 3 — information label system, headline hierarchy, pachinko stage
   Replaces the Phase 2 oval pills / boxed chips / oversized capsule with one
   coherent deep-purple information system on the audited 8px control radius.
   ===================================================================== */

/* --- Icon family sizing -------------------------------------------------- */
.icon { width: 24px; height: 24px; flex: 0 0 auto; }
.icon-chip .icon { width: 24px; height: 24px; color: #fff; }

/* Feature/value icon tile: one dark-purple tile, white icon, one gold accent */
.icon-chip {
  width: 46px;
  height: 46px;
  border-radius: 12px;
  background: var(--td-surface-2);
  border: 1px solid var(--td-border-subtle);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .08);
  position: relative;
}
.icon-chip::after {
  content: "";
  position: absolute;
  left: 10px;
  right: 10px;
  bottom: -1px;
  height: 2px;
  border-radius: 2px;
  background: var(--pachi-gold);
  opacity: .75;
}

/* --- Machine card: ONE shell, type as a restrained accent ----------------
   Phase 4.1 removed the index-based dark/light alternation. Every card in the
   lineup now uses the same deep-plum shell, so the grid reads as one rack of
   cabinets rather than a chequerboard. The machine TYPE is the only variable:
   it sets `--card-accent`, which tints the type chip, the hairline trim and the
   hover border. The type is also printed as text in `.machine-card__cat`, so
   nothing is communicated by colour alone. */
.machine-card {
  --card-accent: var(--pachi-gold);            /* パチンコ — warm gold */
  --card-accent-soft: rgba(255, 199, 44, .30);
  background: var(--pachi-dark-card);
}
.machine-card--pachislot {
  --card-accent: var(--pachi-cyan);            /* パチスロ — cyan */
  --card-accent-soft: rgba(34, 224, 255, .28);
}
.machine-card::after { border-color: var(--card-accent-soft); }
.machine-card:hover { border-color: color-mix(in srgb, var(--card-accent) 60%, transparent); }
.machine-card__cat {
  background: color-mix(in srgb, var(--card-accent) 16%, transparent);
  border: 1px solid color-mix(in srgb, var(--card-accent) 38%, transparent);
  color: color-mix(in srgb, var(--card-accent) 72%, #ffffff);
}
.machine-card__corner {
  position: absolute;
  z-index: 2;
  top: 0;
  right: 0;
  width: 54px;
  height: 54px;
  pointer-events: none;
  background: repeating-linear-gradient(-45deg, var(--card-accent-soft) 0 3px, transparent 3px 8px);
  clip-path: polygon(100% 0, 100% 100%, 0 0);
  opacity: .7;
}
/* `contain`, not `cover`: a cabinet is never cropped. The stage is taller than
   it is wide and the artwork is letterboxed into it if the ratio disagrees. */
.machine-card__media img { object-fit: contain; }
.machine-card__media { background: #1a0126; }
.machine-card__title {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  min-height: 2.7em;
}


/* =====================================================================
   LICENCE PANEL — Phase 5.2 compaction
   Three trust points and the certificate link stay visible; the fact table
   moves into a native <details>. Nothing is hidden from a crawler or from a
   keyboard user — only from the initial scroll.
   ===================================================================== */
.license__points {
  display: flex;
  flex-wrap: wrap;
  gap: 5px;
  margin: 9px 0 10px;
}
.license__point {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 11px;
  border-radius: 999px;
  background: rgba(107, 31, 214, .08);
  border: 1px solid rgba(107, 31, 214, .22);
  font-size: .76rem;
  font-weight: 700;
  /* Phase 5.4: `--text-plum` is a DARK colour meant for light-background
     contexts. This component only ever rendered inside `.is-light` before
     (the retired standalone trust section) — now that it lives in the plain
     footer, `--text-plum` measured ~1.1:1 here, i.e. effectively invisible.
     `--td-text-primary` (white) is correct for this panel's dark surfaces. */
  color: var(--td-text-primary);
}
.license__point-icon { display: grid; place-items: center; color: var(--td-brand-accent-2); }
.license__point-icon .icon { width: 15px; height: 15px; }

.license__details { margin-top: 9px; }
.license__summary {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
  padding: 9px 12px;
  border-radius: 10px;
  background: rgba(107, 31, 214, .07);
  border: 1px solid rgba(107, 31, 214, .22);
  font-size: .82rem;
  font-weight: 900;
  color: var(--td-text-primary);
  cursor: pointer;
  list-style: none;
}
.license__summary:hover,
.license__summary:focus-visible { background: rgba(107, 31, 214, .16); }
.license__summary::-webkit-details-marker { display: none; }
.license__summary::after {
  content: "";
  margin-left: auto;
  width: .5em;
  height: .5em;
  border-right: 2.5px solid currentColor;
  border-bottom: 2.5px solid currentColor;
  transform: rotate(45deg) translateY(-.12em);
  transition: transform .2s var(--motion-ease-out);
}
.license__details[open] .license__summary::after { transform: rotate(-135deg) translateY(.06em); }
.license__details[open] .license__grid { margin-top: 10px; }

.license__age {
  margin-top: 12px;
  font-size: .7rem;
  line-height: 1.7;
  /* Phase 5.4: #6b5b78 measured ~2.5-3:1 against this panel's dark
     backgrounds — well below the 4.5:1 minimum for the visible 18+ /
     responsible-play line. */
  color: var(--td-brand-accent-2);
}


/* =====================================================================
   AMBIENT DECORATION — Phase 5.2

   Original CSS-only motifs: floating pachinko balls, drifting light motes and
   a slow separator sweep. Every one of these is aria-hidden, pointer-events
   none, and disabled wholesale under reduced motion (see motion.css).

   Budget: no section adds more than a handful of nodes, and nothing here
   animates a filter or a full-screen gradient.
   ===================================================================== */
.amb {
  position: absolute;
  pointer-events: none;
  border-radius: 50%;
  will-change: transform;
}
/* A pachinko ball: chrome highlight on a soft sphere. */
.amb--ball {
  width: 14px;
  height: 14px;
  background:
    radial-gradient(circle at 34% 30%, rgba(255, 255, 255, .95), rgba(255, 255, 255, .35) 38%, transparent 62%),
    radial-gradient(circle at 50% 60%, rgba(255, 255, 255, .28), rgba(255, 255, 255, .06));
  box-shadow: 0 2px 6px rgba(0, 0, 0, .28);
  animation: amb-float 13s ease-in-out infinite;
}
.amb--ball:nth-of-type(2) { animation-duration: 17s; animation-delay: -4s; }
.amb--ball:nth-of-type(3) { animation-duration: 21s; animation-delay: -9s; }
/* A small coloured mote. */
.amb--mote {
  width: 7px;
  height: 7px;
  background: var(--amb-color, var(--pachi-yellow));
  box-shadow: 0 0 10px var(--amb-color, var(--pachi-yellow));
  opacity: .7;
  animation: amb-drift 16s linear infinite;
}
@keyframes amb-float {
  0%, 100% { transform: translate3d(0, 0, 0); }
  50%      { transform: translate3d(6px, -18px, 0); }
}
@keyframes amb-drift {
  0%   { transform: translate3d(0, 8px, 0);   opacity: 0; }
  18%  { opacity: .75; }
  82%  { opacity: .75; }
  100% { transform: translate3d(14px, -46px, 0); opacity: 0; }
}


/* Phase 5.2: the panel chrome is what was making the closed mobile state tall,
   not the facts. Everything below tightens the frame, never the content. */
@media (max-width: 767px) {
  .license__inner { padding: 12px 13px 14px; }
  /* Phase 5.5: the headline content and the two "stays visible" controls
     (the certificate link, the age line — see license-panel.njk's own top
     comment) are centred along with the rest of the footer. The disclosure
     summary and its internal fact table stay left-aligned — they are
     functional controls, not a text block, and centring a full-width
     clickable row with a trailing chevron would hurt rather than help
     usability. */
  .license__head { flex-direction: column; align-items: center; text-align: center; gap: 10px; margin-bottom: 2px; }
  .license__icon { width: 34px; height: 34px; border-radius: 9px; }
  .license__icon .icon { width: 17px; height: 17px; }
  .license__title { font-size: .94rem; line-height: 1.4; }
  .license__scope { margin-top: 2px; font-size: .68rem; line-height: 1.5; }
  .license__points { margin: 9px 0 9px; gap: 4px; justify-content: center; }
  .license__point { padding: 5px 9px; font-size: .72rem; }
  /* `margin-inline: auto` only centres a BLOCK box — the base rule makes
     this `inline-flex`, so the display mode changes here too. */
  .license__cert { display: flex; width: fit-content; min-height: 44px; padding: 8px 14px; font-size: .8rem; margin-inline: auto; }
  .license__details { margin-top: 9px; }
  .license__age { margin-top: 8px; font-size: .63rem; line-height: 1.55; text-align: center; }
  .license__grid { gap: 6px; }
  .license__row { padding: 7px 10px; }
  .license__key { font-size: .66rem; }
  .license__val { font-size: .8rem; }
}

/* =====================================================================
   CAMPAIGN GUIDE + MASCOT — Phase 5.3

   Decorative only: aria-hidden in markup, pointer-events none here, so neither
   can ever intercept a tap meant for a CTA or add a screen-reader
   announcement. Two nested wrappers: the outer is the reveal target, the inner
   runs the idle float, so the two transforms never overwrite each other.
   ===================================================================== */
.guide {
  position: absolute;
  z-index: 2;
  pointer-events: none;
  line-height: 0;
}
.guide__float { animation: guide-float 6.5s ease-in-out infinite; }
/* Height-driven, not width-driven. These are tall figures with a lot of
   transparent margin, so sizing by width made the element's BOX overlap the CTA
   even when the artwork visually cleared it. Fixing the height lets each
   placement guarantee the box sits clear of the H1, the badge and every CTA. */
.guide__img { width: auto; height: 100%; display: block; filter: drop-shadow(0 12px 22px rgba(24, 0, 40, .45)); }
.guide__float { height: 100%; }
@keyframes guide-float {
  0%, 100% { transform: translate3d(0, 0, 0); }
  50%      { transform: translate3d(0, -4px, 0); }
}

.mascot {
  position: absolute;
  z-index: 3;
  pointer-events: none;
  line-height: 0;
  animation: mascot-bob 5.2s ease-in-out infinite;
}
.mascot img { width: 100%; height: auto; display: block; }
@keyframes mascot-bob {
  0%, 100% { transform: translate3d(0, 0, 0) rotate(-4deg); }
  50%      { transform: translate3d(0, -7px, 0) rotate(4deg); }
}

/* --- Placement (Phase 5.4: retuned responsive ranges) ---------------------
   Every position is chosen so the character's BOX — not merely its visible
   pixels — sits clear of the H1, the credibility badge, every CTA and (for
   gameplay specifically) the benefit-tile grid below the media stage.
   Heights are explicit for exactly that reason, and are tuned per section per
   breakpoint rather than one global scale:
     mobile ~120-175px · tablet ~190-250px · desktop ~260-340px (hero, as the
   primary/flagship placement, sits at the upper end of each band; the other
   three supporting placements sit mid-band so the family reads as one system). */
/* Phase 5.6: `.guide` is a direct child of `<section class="hero">`, but
   `.hero__inner` (holding the machine fan) is its own stacking context with
   `z-index: 3` — HIGHER than `.guide`'s base `z-index: 2` (components.css,
   top of this file) — so the fan painted over almost the whole guide
   regardless of the individual machines' own z-index, leaving only a sliver
   of her visible past the fan's edge. `z-index: 4` here lifts her above that
   whole stacking context so she renders in full, in front of the fan she is
   meant to stand beside. */
/* Phase 5.8D: hero and gameplay guides scaled up alongside the how-to and
   final-CTA characters so the same figure never appears at wildly different
   apparent sizes in adjacent sections. All fluid, all height-driven. */
/* Phase 5.8F: every offset below is a share of the section's INNER container
   (see the templates), never of the full-bleed section — so no offset may be
   negative. A negative value here is exactly what put the hero guide 342px
   outside the content rail at 1920px. */
.guide--hero     { right: 0; bottom: 0; /* Phase 5.8I: sized from the DESKTOP character/section ratio, not from a
     generic artwork token. 5.8H's clamp(150px, 36vw, 188px) rendered her at
     0.47x the desktop prominence on a phone. */
  /* The proportional height, CAPPED by the machine-fan band. At 320x568 the
     hero holds seven lines of copy plus a CTA in 480px, so there is no
     collision-free room for a proportional figure; `min()` keeps her inside
     the artwork band that the stage itself occupies. */
  /* Unchanged in Phase 5.8K. The roller's frame correction gives its reclaimed
     height back above the fan (sections.css), so the hero's own height — and
     therefore every clearance 5.8I measured here — is exactly as it was. */
  height: min(clamp(196px, 70vw, 300px), clamp(92px, calc(100vh - 568px), 300px));
  z-index: 4; }
.guide--gameplay { right: 0; bottom: 0; height: clamp(200px, 58vw, 235px); }
/* Phase 5.8K — a decorative overlay, not a column.
   Two changes, both about giving the stage back the rail centre:
   · she reaches PAST the rail into the page gutter, so the widest genuinely
     empty band on a phone is the one she stands in. `(100vw - 100%) / -2` is
     the gutter as a negative offset, `100%` being her positioned parent
     (`.gameplay__media`, which is rail-width);
   · `z-index: 1` puts her BEHIND `.gameplay__stage` (z-index 2 below), so the
     overlap that remains hides part of *her* rather than any part of the
     machine demo. Nothing of the screenshot is ever covered. */
@media (max-width: 767px) {
  .guide--gameplay { right: calc((100vw - 100%) / -2); z-index: 1; }
}
/* Phase 5.8F: a SIDE-lane guide, not a figure parked under the button.
   Anchored to `.final-cta__inner` (the shared container) at `left: 0`, so she
   is inside the content rails by construction.

   Below 768px the registration button is full-width by design, so no side lane
   exists next to it — she is aligned to the TOP of the composition instead,
   beside the proof circles, where the centred row leaves real space and the
   section's own top padding gives her height to occupy. From 768px the button
   is capped and centred, which opens a genuine left lane (87px at 768, 203px
   at 1024, 320px at 1440 measured to the button's edge), so she is vertically
   centred on the whole composition there.

   `margin-block: auto` between `top: 0` and `bottom: 0` does the vertical
   centring — deliberately not `transform`, which the shared reveal system
   already owns on this element. */
/* `top: 100%` puts her top edge exactly at the composition's bottom (the
   button), so she occupies the band below it and cannot touch the button, the
   heading or the proof circles. The section's own bottom padding is sized to
   contain her (sections.css). */
/* Phase 5.8I: she moved OUT of the band below the button and into a real
   lane beside the proof/heading group (sections.css). `top: 0` + the lane is
   what lets her be ~5x taller on a phone without touching the CTA. */
/* PHASE 5.8L — below the button on a phone, beside it from 768px.
   5.8I's `top: 0` placement only worked because `.final-cta__inner` carried a
   `padding-left` lane sized from her — i.e. the character was deciding where
   the proof circles, the heading, the supporting line and the button sat. With
   that lane removed (sections.css) the content fills the rail and there is no
   safe horizontal space beside a full-width button, so she takes the section's
   decorative foot band instead: anchored to the bottom-left, bleeding into the
   page gutter for width, clear of every content box by construction.

   She is smaller here than in 5.8I. That is the deliberate trade: content
   centring is unconditional, character prominence is not. The band is occupied
   by two characters rather than empty, so it is not the pre-5.8I dead tail. */
.guide--finalCta {
  left: calc((100vw - 100%) / -2);
  /* `top: 100%` — her TOP edge is exactly the composition's bottom edge (the
     button), so she occupies the band beneath and cannot reach the button, the
     supporting line, the heading or the proof circles whatever the copy
     reflows to. `bottom: 0` would not do this: `.final-cta__inner` ends AT the
     button, so a bottom-anchored figure grows upward across all of it. */
  top: 100%;
  bottom: auto;
  margin-top: 6px;
  height: var(--fc-band-mobile);
}
/* From 768px the button is capped and centred again, so a genuine side lane
   exists and she returns to it — beside the composition, not below it. */
@media (min-width: 768px) {
  .guide--finalCta { left: 0; top: 0; bottom: 0; margin-top: 0; margin-block: auto; height: clamp(190px, 29vw, 232px); }
}

/* How-to guide — Phase 5.8E: a decorative EDGE guide.
   The history here is worth keeping: 5.8B put her in flow (which moved the
   step cards), 5.8C made her an absolute overlay in an empty lane (a ~100px
   figure stranded in blank space, invisible at 768-1023px), 5.8D grew her into
   a flow row beside the introduction copy (which pushed the copy off centre
   and opened a dead band between the introduction and Step 1).

   She is now absolutely positioned against `.howto__intro` and anchored to its
   LEFT edge, bottom-aligned. That side is deliberate: the pose points to her
   right, so from the left edge her gesture sweeps across the centred
   introduction and down into Step 1.

   Out of flow means she costs zero layout height — removing her cannot move
   Step 1, and the introduction stays centred in the shared container.
   `.guide` already carries `pointer-events: none`. */
.guide--howto {
  display: block;
  position: absolute;
  /* Phase 5.8K: anchored to `.howto__head` (ribbon + lockup + intro copy),
     top-left, reaching into the page gutter so she occupies the widest empty
     band the section has. `z-index: 0` puts her under every text layer — the
     ribbon, the 3ステップ lockup and both supporting sentences all paint over
     her, so no glyph can ever be obscured even if a longer translation grows
     into her corner. Nothing she overlaps is content: it is the ray burst. */
  left: 0;
  top: 0;
  bottom: auto;
  /* Phase 5.8G lowered this FLOOR from 132px to 122px — the only adjustment the
     stronger 3ステップ lockup forced, and the reason is purely geometric.

     She is bottom-anchored to `.howto__intro` but taller than it, so she rises
     past its top edge into the head band the lockup lives in. At 320px the
     enlarged lockup is 172px wide and centres at x=74, while a 132px figure
     reached x=76 — a 2px horizontal sliver over the numeral's box. At 0.44
     aspect, clearing it needs her under ~126px tall.

     A floor rather than a `max-width: 359px` override on purpose: 38vw already
     governs from ~321px upward, so this is one continuous curve with no new
     breakpoint, and it changes nothing at or above 347px (where 38vw was
     already past the old floor). 360px and up the container grows faster than
     the lockup and the clearance is 15px to 328px, so nothing there moves. */
  /* Phase 5.8I: proportional to the desktop ratio (5.8H's
     clamp(108px, 34vw, 150px) was 0.67x desktop prominence). */
  /* Phase 5.8K: her height is the HEAD BAND itself, not a token guess. The band
     is ribbon + lockup + introduction copy, which is exactly the region whose
     left side is empty ray field — so she fills the available space by
     construction and can never reach down into the card row however the copy
     reflows. `--howto-guide-h` still governs from 1024px up, where the band is
     shorter than the figure looks good at. */
  /* 6px of clearance below the band, so she cannot touch the top edge of the
     first step card even by a fraction of a pixel. */
  height: calc(100% - 6px);
  width: auto;
  margin: 0;
  z-index: 0;
}
/* DOCUMENTED EXCEPTION at 320 and 360, the same one `guide--hero` already
   carries at those two widths and for the same reason: the ribbon and the two
   supporting sentences are CENTRED on a 284-324px rail, which leaves only
   ~51-67px of clear field at the left edge. A figure proportional to her
   desktop presence would be ~75px wide and would sit under the ribbon and the
   sub-copy. Text must never be overlapped, so at these two widths she is capped
   by the free field instead of by the ratio; from 390px up she is proportional.
   She is proportional again from 1024px, where `--howto-guide-h` governs and
   the band is shorter than the figure reads well at. */
@media (max-width: 389px) {
  .guide--howto { height: min(calc(100% - 6px), 35vw); }
}
@media (min-width: 1024px) {
  .guide--howto { height: var(--howto-guide-h); }
}
/* 768px+ opens a genuinely wide left lane (187px at 768, 303px at 1024, 420px
   at 1440 measured from the container edge to the nearest text), so she grows
   substantially. Her ceiling is the head band's own vertical room, not the
   lane: at 0.44 aspect a taller figure would have to reach past the step cards
   or the ribbon, both of which are text. */
/* Below 1024px the rail leaves her too little room, so she reaches into the
   page gutter as well — `(100vw - 100%) / -2` is that gutter expressed as a
   negative offset against `.howto__head`, which is rail-width. From 1024px the
   container's own slack is wide enough (132px of empty ray field at 1440) that
   the rail edge is both clear of everything and better composed. */
@media (max-width: 1023px) {
  .guide--howto { left: calc((100vw - 100%) / -2); }
}

/* The mascot lives on the artwork side, never over the copy column. */
/* The mascot lives down in the machine-fan zone on the opposite side from the
   guide — the only band of the mobile hero with no copy in it. */
/* Phase 5.8I: fluid, so the small mascots hold their desktop proportion too. */
.mascot--hero  { left: 1%;  bottom: 4%; width: clamp(44px, 14vw, 58px); }
/* Flat, deliberately: the final-CTA section is ~17% TALLER at 320px than at
   1440px (the narrow lane makes the heading wrap more), so a fluid width would
   drop this mascot's character/section ratio below the 0.85x floor there. One
   size keeps the ratio inside the band at every width. */
/* Phase 5.8I: `top: 6%` put her over a proof circle once the lane narrowed the
   content column. She now sits in the section's bottom band, clear of the
   circles, the heading and the full-width button. */
/* She is positioned inside `.final-cta__inner`, which ends at the button, so a
   negative offset is what places her in the section's own band below it. Both
   numbers come from --fc-mascot-band; the extra 4px clears the idle bob. */
.mascot--final { right: 2%;  top: auto; bottom: calc(var(--fc-mascot-band) * -1 - 4px); width: 53px; }
/* Was the ONE mascot that was too BIG on mobile (1.36x desktop prominence). */
.mascot--voices-a { width: clamp(37px, 10.4vw, 52px); }

/* Phase 5.8I: this block used to pin every character to a fixed small size
   below 390px, which is exactly how the mobile figures ended up at half their
   desktop prominence. The clamps above already floor each one proportionally,
   so there is nothing left to override here. */

/* Tablet has more height to spend, but the hero is still one centred column,
   so she stays at the foot beside the machine fan. */
@media (min-width: 600px) {
  .guide--hero     { height: clamp(246px, 32vw, 290px); right: 0; }
  .guide--gameplay { height: clamp(186px, 24vw, 224px); }
  /* Phase 6.5: lifted with the desktop ratio anchor below, so 600-1023px does
     not fall out of the 0.85-1.15x character/section band the suite enforces. */
  .guide--finalCta { height: clamp(190px, 29vw, 232px); }
}


/* Desktop: the hero splits into two columns, so she can stand at full presence
   in the artwork column without ever crossing the copy. */
@media (min-width: 1024px) {
  .guide--hero     { height: clamp(268px, 20.5vw, 312px); right: 0; }
  /* Phase 5.8F: scaled to the smaller stage so she stands in the lane BESIDE
     the machine rather than across its controls. */
  /* PHASE 5.8L — beside the machine on desktop, not behind it.
     5.8K made her independent of the content by stacking her UNDER
     `.gameplay__stage`, which is right for a phone (there is no lane there)
     but wrong here: at 1024-1920 she overlapped the stage by 54.5-74.4px over
     its whole height, so most of the figure was hidden behind the screenshot
     while 291-394px of empty rail sat unused to its right.

     `left: 100%` anchors her left edge to the media wrapper's right edge —
     the wrapper is `max-width`-capped and centred, so this is the start of
     that free lane — and the margin is the deliberate gap. She is therefore
     entirely outside the media box: guide/stage overlap is zero by
     construction, not by tuning. `right: auto` releases the mobile anchor.

     Nothing about the content moves: she is still absolutely positioned
     inside `.gameplay__media`, which has no padding held open for her. */
  .guide--gameplay {
    height: clamp(192px, 15.2vw, 228px);
    right: auto;
    left: 100%;
    margin-left: clamp(16px, 2vw, 32px);
    /* `left: 100%` leaves an absolutely-positioned box no available width, so
       shrink-to-fit collapses it to 0 (the image's own width is `auto` from a
       percentage height, which min-content sizing cannot resolve). The
       artwork's measured ratio gives the width back from the height without
       hard-coding a pixel value or touching `.guide__img { width: auto }` —
       0.706 is the same factor `--gp-guide-w` already uses for this pose. */
    aspect-ratio: 0.706;
    /* No longer under the stage — there is nothing to hide behind, and she
       should sit above the section's decorative background. */
    z-index: 2;
  }
  /* Phase 5.8I: -18% with the artwork pass (was clamp(187px, 15.2vw, 241px)).
     This is the RATIO ANCHOR every narrower width is measured against.

     Phase 6.5 raised it from clamp(138px, 10.9vw, 172px). She measured 73x157
     at 1440 and 80x172 at 1920, against a hero guide at 116x295 and a gameplay
     guide at 155x219 — beside a 1160px composition that read as a sticker
     rather than a character. The lane she stands in at these widths is empty
     by construction (the button is capped and centred from 768px), so the
     extra height is taken from unused space: she stays absolutely positioned,
     `pointer-events: none`, non-focusable, `margin-block: auto` inside
     `.final-cta__inner`, and the ceiling is set so she cannot reach the
     section edge. verify.mjs compares the proof group, heading, copy and CTA
     with her hidden and requires dx/dy/dw/dh = 0. */
  /* Ceiling set by the LANE, not by taste: at 768-1023 the capped, centred
     button leaves ~115px each side, and at 0.467 aspect anything past ~232px
     tall is wider than that and clips the button. The desktop anchor is then
     bounded by the suite's 0.85-1.15x character/section ratio band relative to
     it, which lands at ~259px here — still 65% taller than the 157px she was. */
  .guide--finalCta { height: clamp(235px, 18vw, 265px); left: 0; }
  /* Desktop splits into two columns: the mascot joins the artwork column. */
  /* Phase 5.8I: `top: 12%` collided with the account badge and the sub line
     once the hero got shorter. She drops into the machine-fan band instead. */
  .mascot--hero    { left: 2%; right: auto; top: auto; bottom: 9%; width: 54px; }

}

/* The final-CTA band below the button exists only below 768px, so the negative
   offset that places her in it must not survive above that — and she is
   deliberately SMALLER on desktop than on mobile, because the mobile section is
   ~35% taller (the lane makes the heading wrap) and the ratio band is what
   decides her size, not a single pixel value. */
@media (min-width: 768px) {
  .mascot--final { top: 6%; bottom: auto; width: 44px; }
}

@media (prefers-reduced-motion: reduce) {
  .guide__float, .mascot { animation: none !important; }
}
