/* kiradex.app — "The Field Device".
   The page is the dark around a lit object: a red handheld that opens and
   works. Everything else is drawn from that device's own parts, in the app's
   fixed art palette (Kiradex/Device/DeviceParts.swift): the red shell, the
   dark bezel, the green LCD, the pale lens. One typeface, Martian Mono, at
   two widths: wide and heavy where the shell is lettered, condensed where
   a screen is read. */

@font-face {
    font-family: "Martian Mono";
    src: url("../fonts/martian-mono-latin.woff2") format("woff2");
    font-weight: 100 800;
    font-stretch: 75% 112.5%;
    font-display: swap;
}

:root {
    --red: #d62129;
    --red-shade: #8c0f1a;
    --bezel: #212429;
    --night: #08090b;
    --glass: #9ebd3d;
    --glass-shade: #8fad33;
    --ink: #123317;
    --ink-soft: #244d1f;
    --lens: #b8dbff;

    --text: #f3f0eb;
    --quiet: rgba(243, 240, 235, 0.68);
    --line: rgba(243, 240, 235, 0.14);

    --mono: "Martian Mono", ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, monospace;
    --jp-system: "Hiragino Sans", "Hiragino Kaku Gothic ProN", "Yu Gothic", Meiryo, "Noto Sans CJK JP", sans-serif;
    --jp: "Noto Sans JP", var(--jp-system);
    --gutter: clamp(18px, 4vw, 44px);
    --max: 1180px;
    --bar: 60px;
    --ease: cubic-bezier(0.2, 0.7, 0.2, 1);
    color-scheme: dark;

    /* Space: one scale, used for every gap on the page, so the whole page
       breathes in one rhythm. s1 and s2 are fixed; from s3 up each step is
       fluid between phone and desktop. Section to section is s7, a heading
       to what it introduces is s6, eyebrow to heading s2, heading to lede s3. */
    --s1: 8px;
    --s2: 12px;
    --s3: clamp(16px, 1.6vw, 24px);
    --s4: clamp(24px, 2.8vw, 40px);
    --s5: clamp(40px, 4.6vw, 64px);
    --s6: clamp(64px, 7.5vw, 104px);
    --s7: clamp(96px, 12vw, 176px);

    /* The one light on the page, 0 to 1 across the window and down it.
       js/light.js moves it with the pointer, or with the scroll where there
       is no pointer. Everything that is foil answers to it: the wordmark,
       the years, every card, the pack and the seal. キラ is the name; the
       page should shine the way the cards do. */
    --lx: 0.35;
    --ly: 0.3;
    /* A band of light with a little spectrum in it, for anything foil. */
    --foil: linear-gradient(105deg,
        transparent 30%, rgba(255, 255, 255, 0.36) 42%, rgba(255, 112, 180, 0.22) 47%,
        rgba(120, 200, 255, 0.24) 53%, rgba(255, 255, 255, 0.28) 58%, transparent 70%);
}

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

html { -webkit-text-size-adjust: 100%; background: var(--night); }

/* Grain, so the dark is paper and not a switched-off screen. */
body::after {
    content: ""; position: fixed; inset: 0; z-index: 6; pointer-events: none;
    background: url("../images/grain.png"); opacity: 0.045;
}

body {
    margin: 0;
    background: var(--night);
    color: var(--text);
    font: 400 15px/1.65 var(--mono);
    font-stretch: 75%;
    -webkit-font-smoothing: antialiased;
}

img { max-width: 100%; height: auto; }
a { color: inherit; text-decoration-color: color-mix(in srgb, currentColor 45%, transparent); text-underline-offset: 3px; }
a:hover { text-decoration-color: currentColor; }
:focus-visible { outline: 2px solid var(--lens); outline-offset: 3px; border-radius: 4px; }

/* The Japanese on the site, in Noto Sans JP (OFL, fonts/OFL-noto-sans-jp.txt)
   cut down to the characters used, so every visitor sees the same letters:
   a small file for the home page (キラ, the name, the section labels, the
   illustrators' names) and a larger one for the Japanese sets' names, which
   only a page that uses them fetches. tools/jpfont.py cuts both and writes
   these rules. Japanese card names are set in the reader's own font. */
/* jpfont:begin (written by tools/jpfont.py) */
@font-face {
    font-family: "Noto Sans JP";
    src: url("../fonts/noto-sans-jp-sets.woff2") format("woff2");
    font-weight: 100 900;
    font-display: swap;
    unicode-range: U+3001-3002, U+3005, U+3042, U+3044, U+3046, U+3048, U+304B-304D, U+3051-3053, U+3055-3057, U+305B, U+305D, U+305F-3061, U+3064, U+3066, U+3068, U+306A-306B, U+306E-3070, U+3072, U+3075, U+3078, U+307C, U+307E-307F, U+3081, U+3088-308D, U+3092-3093, U+30A1-30A4, U+30A6-30AD, U+30AF-30C1, U+30C3-30C4, U+30C6-30CB, U+30CD-30D8, U+30DA-30E3, U+30E5-30E7, U+30E9-30ED, U+30EF, U+30F3, U+30FB-30FC, U+4E00, U+4E0A, U+4E16, U+4EAE, U+4EE3, U+4EEE, U+4EF0, U+4EF2, U+4F1D, U+5075, U+5143, U+5149, U+516D, U+51B7, U+5263, U+52C7, U+52D5, U+5316, U+5370, U+53CC-53CD, U+53E4, U+540D, U+5411, U+5486, U+548C, U+54EE, U+55B0, U+56E3, U+56F3, U+5712, U+5730, U+57FA, U+5854, U+58EB, U+5909, U+5927, U+5929, U+59EB, U+5BC6, U+5C01, U+5C71, U+5CF6, U+5E7B, U+5EFA, U+5F18, U+5F35, U+5F37, U+5F71, U+5F85, U+6012, U+6226, U+624B, U+62E1, U+6311, U+63A2, U+63CF, U+6469, U+6483, U+652F, U+653B, U+6589, U+65AD, U+65B0, U+65E5, U+6676, U+66B4, U+6708-6709, U+671B, U+672A, U+672C, U+6749, U+6765, U+6804, U+68EE, U+697D, U+6B21, U+6B63, U+6D77, U+6E80, U+6F06, U+6F20, U+6FC0, U+708E, U+71B1, U+7206, U+7363, U+738B, U+74A7, U+7530, U+753A-753B, U+754C, U+767D, U+76FE, U+77F3, U+7802, U+7814, U+7834, U+795E, U+7981, U+798F, U+79D8, U+7A76, U+7A7A, U+7A81, U+7D19, U+7D50, U+7DF4, U+7FD4, U+8005, U+84BC, U+85E4, U+8679, U+885D, U+88C2, U+8972, U+8987, U+898B, U+899A, U+8A66, U+8A9E, U+8AAC, U+8D64, U+8D85, U+8DE1, U+8FC5, U+9006, U+9023, U+907A, U+914D, U+9177, U+9192, U+91CE, U+91D1, U+9280, U+9583, U+9593, U+95C7, U+95D8, U+9632, U+96F7, U+96FB, U+9752, U+9762, U+9802, U+98A8, U+98DB, U+9ED2, U+9F13, U+FF06, U+FF1A;
}
@font-face {
    font-family: "Noto Sans JP";
    src: url("../fonts/noto-sans-jp-kira.woff2") format("woff2");
    font-weight: 100 900;
    font-display: swap;
    unicode-range: U+3001-3002, U+3042, U+304B, U+304D, U+3052-3053, U+3057, U+3060, U+3064, U+306B, U+306E, U+3070, U+3078, U+307E, U+308B, U+3093, U+30A3, U+30A6, U+30AB, U+30AD, U+30AF-30B0, U+30B3, U+30B9, U+30C3, U+30C7, U+30C9, U+30D5, U+30E9, U+30FB-30FC, U+4E0A, U+4EAE, U+516D, U+548C, U+59EB, U+5EFA, U+5F18, U+624B, U+63CF, U+6589, U+65E5, U+6709, U+672C, U+6749, U+68EE, U+6B63, U+6E80, U+7530, U+753B, U+798F, U+7D19, U+85E4, U+8A9E, U+91CE, U+9762;
}
/* jpfont:end */
[lang="ja"] { font-family: var(--jp); }
.roster[lang="ja"] { font-family: var(--jp-system); }

h1, h2, h3, p, ol, ul, dl, dd { margin: 0; }
ol, ul { padding: 0; list-style: none; }

.wrap { width: 100%; max-width: var(--max); margin-inline: auto; padding-inline: var(--gutter); }
.narrow { max-width: 760px; }

.skip { position: absolute; left: -9999px; top: 8px; background: var(--text); color: var(--night); padding: 8px 12px; border-radius: 6px; z-index: 10; }
.skip:focus { left: 8px; }

/* The lettering on the shell: wide, heavy, spaced, as KIRADEX is on the cover. */
h2, .wordmark, .brand span, .button {
    font-stretch: 112.5%;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: 0.14em;
}

.eyebrow { font-size: 12.5px; color: var(--quiet); letter-spacing: 0.02em; }
.lede { font-size: clamp(15.5px, 1.25vw, 17.5px); line-height: 1.6; max-width: 56ch; text-wrap: pretty; }
.quiet { color: var(--quiet); font-size: 13.5px; }
.fine { color: var(--quiet); font-size: 12px; line-height: 1.6; max-width: 78ch; }
.fine + .fine { margin-top: 10px; }

/* ---- Bar ---------------------------------------------------------------- */

.bar { height: var(--bar); position: relative; z-index: 3; }
.bar-row { height: 100%; display: flex; align-items: center; justify-content: space-between; gap: 16px; }
.brand { display: inline-flex; align-items: center; gap: 10px; text-decoration: none; }
.brand img { border-radius: 7px; display: block; }
.brand span { font-size: 13px; }
.bar-links { display: flex; gap: clamp(14px, 3vw, 28px); font-size: 13.5px; }
.bar-links a { text-decoration: none; color: var(--quiet); padding: 12px 0; }
.bar-links a:hover, .bar-links a[aria-current="page"] { color: var(--text); }

/* ---- Hero --------------------------------------------------------------- */

.hero {
    position: relative;
    min-height: calc(100svh - var(--bar));
    display: grid;
    grid-template-rows: minmax(0, 1fr) auto auto;
    isolation: isolate;
}
/* The light the device stands in: its own red, thrown on the dark. */
.hero::before {
    content: "";
    position: absolute;
    inset: calc(-1 * var(--bar)) 0 0;
    z-index: -1;
    background:
        radial-gradient(58% 50% at calc(38% + var(--lx) * 24%) calc(36% + var(--ly) * 16%), rgba(214, 33, 41, 0.34), rgba(140, 15, 26, 0.14) 46%, transparent 72%),
        linear-gradient(to bottom, transparent 70%, var(--night));
    pointer-events: none;
}

.hero-field { position: relative; min-height: clamp(380px, 58svh, 760px); container-type: inline-size; }
.stage { position: absolute; inset: 0; z-index: 1; }
.stage canvas {
    position: absolute; inset: 0; width: 100%; height: 100%; display: block;
    opacity: 0; transition: opacity 0.5s var(--ease);
    -webkit-tap-highlight-color: transparent;
    touch-action: manipulation;
    -webkit-user-select: none; user-select: none;
    outline: none;
}
:root[data-stage="ready"] .stage canvas { opacity: 1; }
/* The companion. Scrolled past the hero on a wide screen, the device comes
   along in the corner: point at a card anywhere on the page and it holds
   that card up. A tap on it goes back to the top. */
:root[data-companion="on"] .stage {
    position: fixed; inset: auto 12px 12px auto; width: 200px; height: 160px;
    animation: companion-in 0.5s var(--ease);
    transition: width 0.45s var(--ease), height 0.45s var(--ease);
}
/* Awake: holding a card up, it grows, with its own dark to stand in so the card reads over anything. */
:root[data-companion="on"][data-device="open"] .stage {
    width: min(380px, 30vw); height: min(290px, 23vw);
    background: radial-gradient(closest-side, rgba(8, 9, 11, 0.94) 55%, rgba(8, 9, 11, 0.6) 80%, transparent);
}
/* The hero is its own layer, and comes before the rest of the page: lifted,
   so the companion in it sits over the sections it rides across. */
:root[data-companion="on"] .hero { z-index: 5; }
:root[data-companion="on"] .stage canvas { cursor: pointer; }
@keyframes companion-in { from { opacity: 0; translate: 0 24px; } }
.stage canvas[data-over="inner"], .stage canvas[data-over="outer"] { cursor: pointer; }
.stage canvas[data-over="body"] { cursor: grab; }
/* Closed, any part of the device opens it. */
:root[data-device="closed"] .stage canvas[data-over="body"] { cursor: pointer; }
.stage canvas.is-turning { cursor: grabbing; }

.wordmark {
    position: absolute;
    inset: 0 0 auto;
    margin: 0;
    padding-top: clamp(12px, 2.6svh, 34px);
    text-align: center;
    font-size: clamp(54px, 15.6vw, 250px);
    line-height: 1;
    letter-spacing: 0.06em;
    /* The spacing after the last letter would push the word off centre. */
    text-indent: 0.06em;
    white-space: nowrap;
    /* Foil lettering: the shell's red, with the light running across it. */
    color: transparent;
    background: linear-gradient(105deg,
        var(--red) 0 36%, #f2434c 43%, #ffc9cf 48.5%, #ff86a8 51%, #b8dbff 53.5%, #f2434c 59%, var(--red) 66% 100%);
    background-size: 320% 100%;
    background-position: calc(100% - var(--lx) * 100%) 0;
    -webkit-background-clip: text; background-clip: text;
    opacity: 0.9;
    transition: opacity 0.9s var(--ease);
    -webkit-user-select: none; user-select: none;
}

/* The name in katakana over the wordmark, the way Japanese type annotates
   a foreign name: ruby, small and spaced across the word, in a quiet ink
   rather than the foil. */
.wordmark ruby { ruby-position: over; ruby-align: center; }
.wordmark rt {
    font: 500 clamp(11px, 1.35vw, 20px)/1 var(--jp);
    letter-spacing: 1em;
    text-indent: 1em;
    text-transform: none;
    color: var(--quiet); -webkit-text-fill-color: var(--quiet);
    padding-bottom: 0.8em;
}
.wordmark rp { display: none; }

/* Dust in the lamp light, behind the device. */
.dust { position: absolute; inset: 0; pointer-events: none; overflow: hidden; }
.dust i {
    position: absolute; width: 3px; height: 3px; border-radius: 50%;
    background: #ffd9dc; opacity: 0.22; filter: blur(0.6px);
    animation: dust 22s ease-in-out infinite alternate;
}
.dust i:nth-child(1) { left: 12%; top: 30%; animation-duration: 26s; }
.dust i:nth-child(2) { left: 24%; top: 68%; animation-duration: 19s; animation-delay: -6s; width: 2px; height: 2px; }
.dust i:nth-child(3) { left: 37%; top: 18%; animation-duration: 31s; animation-delay: -12s; }
.dust i:nth-child(4) { left: 58%; top: 80%; animation-duration: 24s; animation-delay: -3s; width: 2px; height: 2px; }
.dust i:nth-child(5) { left: 67%; top: 24%; animation-duration: 28s; animation-delay: -15s; }
.dust i:nth-child(6) { left: 78%; top: 58%; animation-duration: 21s; animation-delay: -9s; width: 4px; height: 4px; opacity: 0.14; }
.dust i:nth-child(7) { left: 88%; top: 36%; animation-duration: 33s; animation-delay: -20s; width: 2px; height: 2px; }
.dust i:nth-child(8) { left: 46%; top: 50%; animation-duration: 29s; animation-delay: -17s; opacity: 0.12; }
@keyframes dust {
    from { translate: 0 0; }
    50% { translate: 22px -34px; }
    to { translate: -18px -70px; }
}
/* Once the device is in front of it, open, the word steps back. */
:root[data-stage="ready"][data-device="open"] .wordmark { opacity: 0.2; }

/* While the device loads: a glass globe where the device will stand, with
   plasma charging up inside it (js/orb draws the plasma on the canvas; the
   glass is drawn here). It grows more violent as the three boot stages
   pass, and when the device is ready it folds into it.
   Without WebGL there is no plasma, and the device's three boot lights show
   in the glass instead: the first lit when the page's script starts, the
   second when the device's code has arrived, the third when it is built. */
.boot {
    position: absolute; left: 50%; top: 50%; translate: -50% -50%;
    /* Sized from the field's width and the window's height: the field's own
       height reads as nothing to a container query when it comes from
       min-height alone, as it does on a phone. */
    width: min(58cqw, 44svh, 420px); aspect-ratio: 1;
    display: flex; align-items: center; justify-content: center; gap: 14px;
    border-radius: 50%;
    background:
        radial-gradient(circle at 34% 24%, rgba(255, 255, 255, 0.16), transparent 22%),
        radial-gradient(circle at 50% 50%, rgba(8, 9, 11, 0.94) 0 62%, rgba(8, 9, 11, 0.8) 100%);
    box-shadow:
        inset 0 0 0 1px rgba(184, 219, 255, 0.2),
        inset 0 -18px 50px rgba(214, 33, 41, 0.2),
        0 0 90px rgba(214, 33, 41, 0.3);
    opacity: 0; scale: 0.92;
    transition: opacity 0.5s var(--ease), scale 0.6s var(--ease);
    pointer-events: none;
}
@container (max-width: 700px) {
    .boot { width: min(74cqw, 38svh); }
}
:root[data-boot] .boot { opacity: 1; scale: 1; }
/* Ready: the globe folds into the device coming in behind it. */
:root[data-stage="ready"] .boot { opacity: 0; scale: 0.3; transition: opacity 0.45s var(--ease) 0.12s, scale 0.6s cubic-bezier(0.6, 0, 0.9, 0.4); }
:root[data-device="none"] .boot { opacity: 0; }
/* The shader's globe fills nine tenths of its canvas; the canvas overhangs
   the glass by the rest so the two edges meet. */
.boot-orb { position: absolute; inset: -5.56%; width: 111.12%; height: 111.12%; opacity: 0; transition: opacity 0.5s var(--ease); }
:root[data-orb="on"] .boot-orb { opacity: 1; }
:root[data-orb="on"] .boot span { display: none; }
.boot span { width: 10px; height: 10px; border-radius: 50%; background: #fff; opacity: 0.25; }
:root[data-boot="1"] .boot span:nth-of-type(-n + 1),
:root[data-boot="2"] .boot span:nth-of-type(-n + 2),
:root[data-boot="3"] .boot span { opacity: 1; }
:root[data-boot="1"] .boot span:nth-of-type(2),
:root[data-boot="2"] .boot span:nth-of-type(3) { animation: boot-blink 0.8s steps(1) infinite; }
@keyframes boot-blink { 0%, 49% { opacity: 0.25; } 50%, 100% { opacity: 1; } }

.stage-fallback { display: none; }
:root[data-device="none"] .stage-fallback, .stage-noscript {
    display: block; position: absolute; left: 50%; top: 56%; translate: -50% -50%;
    border-radius: 22.5%; box-shadow: 0 30px 80px rgba(0, 0, 0, 0.6); z-index: 1;
}

.hero-foot {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: end;
    gap: var(--s3) clamp(24px, 5vw, 72px);
    padding-block: var(--s4) var(--s3);
}
.hero-copy { display: grid; gap: var(--s2); }
/* キラ, the word itself, a little larger than the sentence around it. */
.hero-copy .eyebrow [lang="ja"] { font-size: 1.35em; font-weight: 700; color: var(--text); vertical-align: -0.04em; }
.hero-actions { display: grid; justify-items: end; gap: 10px; }
.status { font-size: 12.5px; color: var(--quiet); }

/* A strip of LCD that reports what the device on the page is doing. */
.readout {
    display: inline-flex; align-items: center; gap: 8px;
    padding: 5px 10px 4px;
    border: 3px solid var(--bezel);
    border-radius: 8px;
    color: var(--ink);
    background: var(--glass) repeating-linear-gradient(to bottom, var(--glass-shade) 0 1px, transparent 1px 3px);
    font-size: 11px; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase;
    line-height: 1.5;
}
.readout-light { width: 8px; height: 8px; border-radius: 50%; background: var(--glass-shade); }
.readout[data-state="on"] .readout-light { background: var(--ink); }
.readout[data-state="busy"] .readout-light { animation: blink 0.8s steps(1) infinite; }
@keyframes blink { 0%, 49% { background: var(--glass-shade); } 50%, 100% { background: var(--ink); } }

.button {
    appearance: none;
    display: inline-flex; align-items: center; justify-content: center;
    text-decoration: none;
    border: 0;
    border-radius: 12px;
    min-height: 48px;
    padding: 0 22px;
    background: var(--red);
    color: #fff;
    font: 800 12.5px/1 var(--mono);
    font-stretch: 112.5%;
    cursor: pointer;
    box-shadow: 0 1px 0 rgba(255, 255, 255, 0.22) inset, 0 10px 30px rgba(214, 33, 41, 0.28);
    transition: background-color 0.15s var(--ease), translate 0.15s var(--ease);
}
.button:hover { background: #e02a33; }
.button:active { background: var(--red-shade); translate: 0 1px; }
/* The device is already open and working: closing it is something to try,
   not the thing to do. */
.button-quiet {
    background: transparent; color: var(--text);
    box-shadow: 0 0 0 1px var(--line) inset;
    min-height: 44px;
}
.button-quiet:hover { background: rgba(243, 240, 235, 0.08); }
.button-quiet:active { background: rgba(243, 240, 235, 0.14); }
/* Until the device is there, there is nothing for it to close. */
/* Only the hero's own button: a link dressed as a button elsewhere on the page (the App Store, the lists) does not wait on the device. */
:root:not([data-stage="ready"]) .hero .button { visibility: hidden; }
:root[data-device="none"] .hero .button, :root[data-device="none"] .readout, :root[data-device="none"] .hero-hint { display: none; }

.hero-hint {
    font-size: 12.5px;
    color: var(--quiet);
    padding-bottom: clamp(18px, 3svh, 34px);
    opacity: 0;
    transition: opacity 0.6s var(--ease);
}
:root[data-stage="ready"] .hero-hint { opacity: 1; }
.hint-open, :root[data-device="open"] .hint-closed { display: none; }
:root[data-device="open"] .hint-open { display: inline; }

/* ---- A letter to the cards -----------------------------------------------
   Thirty years of eras, and the people who drew them. The cards here are
   whole cards from the public catalog, asked for by the visitor's browser,
   each credited and each a way into the device: no cropped art, no logos.
   They lie on the dark the way they would on a table under one lamp. */

.letter, .hands { padding-block: var(--s7) 0; position: relative; }
.hands { padding-bottom: var(--s7); }
.letter-head { display: grid; gap: var(--s2); margin-bottom: var(--s6); }
.letter-head h2 { font-size: clamp(26px, 5.2vw, 68px); line-height: 1.05; text-wrap: balance; }
.letter-head .lede, .shell-head h2 + p { margin-top: var(--s2); }
.letter-notice { margin-top: var(--s6); }

/* A card. It leans toward the pointer and its foil catches the light:
   js/letter.js sets --rx and --ry (degrees) and --mx and --my (per cent). */
.tcg-card {
    appearance: none; display: block; width: 100%; padding: 0; border: 0;
    aspect-ratio: 63 / 88; border-radius: 4.6% / 3.3%;
    background: #15171b; color: var(--quiet);
    position: relative; overflow: hidden; cursor: pointer;
    transform: perspective(900px) rotateY(calc(var(--rx, 0) * 1deg)) rotateX(calc(var(--ry, 0) * 1deg));
    transition: transform 0.5s var(--ease);
    /* The shadow falls away from the light. */
    box-shadow: 0 1px 0 rgba(255, 255, 255, 0.08) inset,
        calc((0.5 - var(--lx)) * 34px) calc(16px + (0.5 - var(--ly)) * 22px) 38px rgba(0, 0, 0, 0.55);
    -webkit-tap-highlight-color: transparent;
}
.tcg-card.is-held { transition: none; }
.tcg-card img { display: block; width: 100%; height: 100%; object-fit: cover; }
/* The foil: a band of light and a little spectrum, slid across the card by the pointer. */
.tcg-card::after {
    content: ""; position: absolute; inset: 0; pointer-events: none;
    background: var(--foil);
    background-size: 260% 260%;
    /* Under a mouse, the card's own light (js/letter.js); otherwise the page's. */
    background-position: var(--mx, calc(100% - var(--lx) * 100%)) var(--my, calc(100% - var(--ly) * 100%));
    mix-blend-mode: screen;
    opacity: 0.4; transition: opacity 0.3s var(--ease);
}
.tcg-card.is-held::after, .tcg-card:focus-visible::after { opacity: 1; }
.tcg-card.is-held, .tcg-card:focus-visible { box-shadow: 0 1px 0 rgba(255, 255, 255, 0.12) inset, 0 26px 60px rgba(0, 0, 0, 0.7), 0 0 40px rgba(214, 33, 41, 0.25); }
/* A card whose picture could not be had says its name instead. */
.tcg-missing { display: none; }
.tcg-card.is-missing img { display: none; }
.tcg-card.is-missing .tcg-missing {
    display: grid; place-items: center; position: absolute; inset: 0; padding: 10%;
    font-size: 12px; font-weight: 700; text-align: center; border: 1px solid var(--line); border-radius: inherit;
}

/* The binder: one page an era, turned sideways. The next page shows at the
   edge, so it is plain there is more. */
.binder-frame { position: relative; }
.binder {
    display: grid; grid-auto-flow: column; grid-auto-columns: min(86vw, 1040px);
    gap: clamp(14px, 2vw, 28px);
    padding-inline: max(var(--gutter), (100vw - 1040px) / 2);
    overflow-x: auto; overscroll-behavior-x: contain;
    scroll-snap-type: x mandatory; scroll-padding-inline: max(var(--gutter), (100vw - 1040px) / 2);
    scrollbar-width: none;
    padding-block: 8px 28px;
}
.binder::-webkit-scrollbar { display: none; }
.binder:focus-visible { outline-offset: -4px; }
.era {
    scroll-snap-align: start;
    display: grid; grid-template-columns: minmax(0, 0.9fr) minmax(0, 1fr); align-items: center;
    gap: clamp(16px, 3vw, 48px);
    min-height: clamp(380px, 46vw, 520px);
    padding: clamp(20px, 3.4vw, 48px);
    border-radius: 22px;
    background:
        radial-gradient(70% 90% at 78% 50%, rgba(214, 33, 41, 0.24), transparent 70%),
        linear-gradient(160deg, #14161a, #0b0c0f);
    box-shadow: 0 0 0 1px var(--line) inset;
    overflow: hidden;
}
.era-words { display: grid; gap: 8px; align-content: center; min-width: 0; }
/* The year, lettered as the wordmark is but in outline: the era is the
   frame, the cards are what is in it. */
.era-year {
    font-stretch: 112.5%; font-weight: 800; letter-spacing: 0.02em; line-height: 0.9;
    font-size: clamp(64px, 9.2vw, 132px);
    color: transparent; -webkit-text-stroke: 2px var(--red);
    margin-left: -0.04em;
    position: relative;
}
/* The era being read: its year fills with foil. */
.era-year::after {
    content: attr(data-year); position: absolute; left: 0; top: 0;
    -webkit-text-stroke: 0;
    background: linear-gradient(105deg, var(--red) 0 30%, #ff5a62 40%, #ffd0d4 48%, #b8dbff 53%, #ff86a8 58%, var(--red) 70% 100%);
    background-size: 280% 100%;
    background-position: calc(100% - var(--lx) * 100%) 0;
    -webkit-background-clip: text; background-clip: text;
    opacity: 0; transition: opacity 0.9s var(--ease);
}
.era.is-current .era-year::after { opacity: 1; }
/* The foil of its day. The first eras' years fill with a cosmos: sparkle
   drifting through the red as the light moves. The recent eras' years with
   a brushed sheen, fine lines down the foil. An evocation of how the cards
   of each era shone, not a reproduction of anyone's finish. */
.era[data-foil="cosmos"] .era-year::after {
    background:
        radial-gradient(circle, #fff 0 0.7px, transparent 1.4px),
        radial-gradient(circle, rgba(255, 255, 255, 0.55) 0 0.6px, transparent 1.3px),
        radial-gradient(circle, rgba(184, 219, 255, 0.7) 0 0.9px, transparent 1.8px),
        radial-gradient(circle, rgba(255, 255, 255, 0.4) 0 0.5px, transparent 1.2px),
        linear-gradient(105deg, var(--red) 0 30%, #ff5a62 40%, #ffd0d4 48%, #b8dbff 53%, #ff86a8 58%, var(--red) 70% 100%);
    /* Four drifts of sparkle at sizes that share no factor, so no grid shows. */
    background-size: 23px 19px, 31px 37px, 53px 41px, 17px 43px, 280% 100%;
    background-position:
        calc(var(--lx) * 44px) calc(var(--ly) * 30px),
        calc(var(--lx) * -26px + 9px) calc(var(--ly) * 18px + 7px),
        calc(var(--lx) * 60px + 21px) calc(var(--ly) * -40px + 13px),
        calc(var(--lx) * -50px + 5px) calc(var(--ly) * 24px + 29px),
        calc(100% - var(--lx) * 100%) 0;
    -webkit-background-clip: text; background-clip: text;
}
.era[data-foil="sheen"] .era-year::after {
    background:
        repeating-linear-gradient(90deg, rgba(255, 255, 255, 0.34) 0 1px, transparent 1px 4px),
        repeating-linear-gradient(90deg, transparent 0 22px, rgba(255, 255, 255, 0.18) 22px 23px, transparent 23px 51px),
        linear-gradient(105deg, var(--red) 0 30%, #ff5a62 40%, #ffd0d4 48%, #b8dbff 53%, #ff86a8 58%, var(--red) 70% 100%);
    background-size: auto, auto, 280% 100%;
    background-position: calc(var(--lx) * 8px) 0, calc(var(--lx) * -40px) 0, calc(100% - var(--lx) * 100%) 0;
    -webkit-background-clip: text; background-clip: text;
}
.era h3 { font-size: clamp(20px, 2.4vw, 30px); line-height: 1.15; font-weight: 700; }
.era-facts { font-size: 12px; font-weight: 500; text-transform: uppercase; letter-spacing: 0.03em; color: var(--quiet); }
.era-opener { font-size: 13.5px; color: var(--quiet); margin-top: 10px; max-width: 38ch; }
.credits { display: grid; gap: 4px; font-size: 13.5px; }
.credits span:first-child { font-weight: 700; }
.credit-by { color: var(--quiet); }

/* Three cards fanned in the hand: the most sought-after in front. */
.fan { position: relative; height: 100%; min-height: 300px; display: grid; place-items: center; }
.fan li { grid-area: 1 / 1; width: clamp(128px, 17vw, 228px); transition: translate 0.5s var(--ease), rotate 0.5s var(--ease); }
.fan li:nth-child(1) { z-index: 3; }
.fan li:nth-child(2) { z-index: 2; translate: -62% 4%; rotate: -11deg; }
.fan li:nth-child(3) { z-index: 1; translate: 62% 4%; rotate: 11deg; }
.fan li:hover, .fan li:focus-within { z-index: 4; }
.fan li:nth-child(2):hover, .fan li:nth-child(2):focus-within { translate: -72% 0; rotate: -6deg; }
.fan li:nth-child(3):hover, .fan li:nth-child(3):focus-within { translate: 72% 0; rotate: 6deg; }

/* The pack. The binder arrives sealed in foil, in Kiradex's own art; a tap
   tears the top off, the wrapper drops away, and the first era's cards come
   up out of it into the hand. .letter has data-seal: sealed, opening, open. */
.fan { grid-column: 2; grid-row: 1; }
.pack {
    appearance: none; border: 0; padding: 0; background: none; cursor: pointer;
    grid-column: 2; grid-row: 1; place-self: center; z-index: 5;
    width: clamp(200px, 24vw, 300px); position: relative;
    filter: drop-shadow(calc((0.5 - var(--lx)) * 30px) calc(20px + (0.5 - var(--ly)) * 20px) 30px rgba(0, 0, 0, 0.6));
    transition: translate 0.4s var(--ease), rotate 0.4s var(--ease);
    rotate: -3deg;
    -webkit-tap-highlight-color: transparent;
}
.pack[hidden] { display: none; }
.pack:hover { translate: 0 -6px; rotate: -1deg; }
.pack svg { display: block; width: 100%; height: auto; overflow: visible; }
.pack::after {
    content: ""; position: absolute; inset: 0 0 3%; pointer-events: none;
    background: var(--foil); background-size: 260% 260%;
    background-position: calc(100% - var(--lx) * 100%) calc(100% - var(--ly) * 100%);
    mix-blend-mode: screen; opacity: 0.85; transition: opacity 0.3s var(--ease);
}
.pack-name { font: 800 30px var(--mono); font-stretch: 112.5%; letter-spacing: 5px; fill: #fff; }
.pack-facts { font: 700 12px var(--mono); font-stretch: 75%; letter-spacing: 1.5px; fill: rgba(255, 255, 255, 0.85); }
.pack-tap { font: 700 13px var(--mono); font-stretch: 112.5%; letter-spacing: 3px; fill: #fff; animation: pack-ask 1.6s ease-in-out infinite; }
@keyframes pack-ask { 50% { opacity: 0.35; } }
.pack-top, .pack-body { transition: transform 0.55s cubic-bezier(0.5, 0, 0.8, 0.4), opacity 0.45s linear; transform-box: fill-box; }
.pack-top { transform-origin: left bottom; }

/* Sealed: only the pack, on a bare first page, and a line where the words will be. */
.pack-note {
    display: none; grid-column: 1; grid-row: 1; align-self: center;
    font-size: clamp(15px, 1.6vw, 19px); line-height: 1.5; color: var(--quiet);
}
[data-seal="sealed"] .pack-note { display: block; }
[data-seal="sealed"] .binder, [data-seal="opening"] .binder { overflow: hidden; }
[data-seal="sealed"] .era-words, [data-seal="sealed"] .era:not(:first-child), [data-seal="sealed"] .ruler { opacity: 0; }
[data-seal="sealed"] .ruler { pointer-events: none; }
.era-words, .era, .ruler { transition: opacity 0.9s var(--ease) 0.5s; }
[data-seal="sealed"] .era:first-child .fan li { translate: 0 8%; rotate: 0deg; scale: 0.8; opacity: 0; pointer-events: none; }
/* Opening: the top tears off, the wrapper drops, the cards come up one by one. */
[data-seal="opening"] .pack { pointer-events: none; }
[data-seal="opening"] .pack::after { opacity: 0; }
[data-seal="opening"] .pack-top { transform: translate(40px, -90px) rotate(28deg); opacity: 0; }
[data-seal="opening"] .pack-body { transform: translateY(46%); opacity: 0; transition-delay: 0.42s, 0.55s; }
.era:first-child .fan li { transition: translate 0.7s var(--ease), rotate 0.7s var(--ease), scale 0.7s var(--ease), opacity 0.3s linear; }
[data-seal="opening"] .era:first-child .fan li:nth-child(1) { transition-delay: 0.5s; }
[data-seal="opening"] .era:first-child .fan li:nth-child(2) { transition-delay: 0.68s; }
[data-seal="opening"] .era:first-child .fan li:nth-child(3) { transition-delay: 0.86s; }
.visually-hidden { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }

/* The years, as a ruler under the binder: where you are, and a way to anywhere. */
.ruler { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: 10px; margin-top: 6px; }
.ruler ol { display: flex; overflow-x: auto; scrollbar-width: none; border-top: 1px solid var(--line); }
.ruler ol::-webkit-scrollbar { display: none; }
.ruler li { flex: 1 0 auto; }
.ruler button {
    appearance: none; background: none; border: 0; color: var(--quiet); cursor: pointer;
    font: 500 12px/1.3 var(--mono); font-stretch: 75%;
}
.ruler li button { display: grid; gap: 2px; justify-items: start; width: 100%; min-height: 48px; padding: 10px 12px 6px 0; position: relative; text-align: left; }
.ruler li button::before { content: ""; position: absolute; left: 0; top: -1px; width: 1px; height: 8px; background: var(--quiet); }
.ruler li button span:first-child { font-weight: 700; font-size: 13px; }
.ruler-name { white-space: nowrap; opacity: 0.8; }
.ruler li button:hover, .ruler li button[aria-current="true"] { color: var(--text); }
.ruler li button[aria-current="true"]::before { height: 14px; width: 3px; background: var(--red); }
.ruler-step { width: 44px; height: 44px; border-radius: 50%; box-shadow: 0 0 0 1px var(--line) inset; font-size: 16px; }
.ruler-step:hover { background: rgba(243, 240, 235, 0.08); color: var(--text); }
.ruler-step:disabled { opacity: 0.3; cursor: default; }

/* The hands: a name, and four of their cards from first year to latest. */
.artists { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 460px), 1fr)); gap: var(--s6) var(--s5); }
.artist { display: grid; gap: var(--s1); align-content: start; border-top: 1px solid var(--line); padding-top: var(--s3); }
.artist h3 { font-stretch: 112.5%; font-weight: 800; text-transform: uppercase; letter-spacing: 0.08em; font-size: clamp(17px, 2vw, 24px); line-height: 1.2; }
.row { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: clamp(8px, 1.4vw, 16px); margin-top: var(--s3); }
.row li { display: grid; gap: 8px; }
.row-year { font-size: 11px; font-weight: 700; color: var(--quiet); letter-spacing: 0.04em; }

/* ---- Props: things from the table, in 3D, set about the page -------------
   js/props.js draws each into its placeholder through one fixed canvas.
   The placeholder only says where and how big. */
.prop { position: absolute; right: 0; top: 50%; translate: 0 -50%; width: clamp(150px, 17vw, 250px); aspect-ratio: 1; pointer-events: none; }
.prop canvas { display: block; width: 100%; height: 100%; }
.prop-wide { width: clamp(220px, 26vw, 380px); aspect-ratio: 3 / 2; }
.letter-head, .shell-head, .release-row { position: relative; }
/* The section's name in Japanese, set vertically in the margin beside the
   heading, as a label runs down the spine of a book. Only where the margin
   has room for it. */
.spine {
    display: none;
    position: absolute; left: calc(-1 * var(--gutter) - 36px); top: 0.2em;
    writing-mode: vertical-rl; text-orientation: mixed;
    font: 500 13px/1 var(--jp); letter-spacing: 0.32em; color: var(--quiet);
    white-space: nowrap;
}
.shell .spine { color: rgba(255, 255, 255, 0.72); }
@media (min-width: 1320px) { .spine { display: block; } }
/* Room at the right for the prop, so the words never run under it. */
.letter-head, .shell-head { padding-right: clamp(150px, 19vw, 280px); }
.shell-head { min-height: clamp(170px, 15vw, 230px); align-content: start; }
.shell-head .prop { top: 45%; }
.release-row { padding-right: clamp(220px, 28vw, 400px); }

/* ---- The shell: what it does, on the device's own screens ---------------- */

.shell {
    position: relative;
    padding-block: var(--s7);
    background: linear-gradient(135deg, var(--red), var(--red-shade));
}
/* The hinge down the leading edge, as on the cover. */
.shell::before {
    content: "";
    position: absolute; inset: 0 auto 0 0;
    width: clamp(10px, 1.6vw, 22px);
    background: linear-gradient(to right, var(--bezel), var(--red-shade));
}
.shell-head { display: grid; gap: var(--s2); margin-bottom: var(--s6); }
.shell-head h2 { font-size: clamp(26px, 4.6vw, 60px); line-height: 1.05; }
.shell-head p { font-size: 14.5px; color: rgba(255, 255, 255, 0.86); max-width: 52ch; }
.shell-eyebrow { color: rgba(255, 255, 255, 0.72); }

/* ---- The bank: six screens from the device, each the size its content wants.
   On a wide screen the status readout and the card's entry are tall and the
   rest fill around them, like a wall of instruments. */
.bank { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); gap: var(--s3); }
.bank-status { grid-column: span 7; }
.bank-entry { grid-column: span 5; grid-row: span 2; }
.bank-progress { grid-column: span 7; }
.bank-chart { grid-column: span 7; }
.bank-fold { grid-column: span 5; }
.bank-yours { grid-column: span 12; }
/* The inspector's stage: the card itself, standing in the dark above the entry. */
.screen-stage { display: grid; place-items: center; padding: 14px 0 6px; }
.screen-stage .tcg-card { width: min(62%, 190px); }
.bank .lcd-glass { gap: 10px; }
.bank .lcd-glass h3 { font-size: clamp(19px, 1.7vw, 24px); }
.screen-body { display: grid; gap: 6px; margin-top: auto; padding-top: 14px; border-top: 1px dashed rgba(18, 51, 23, 0.35); }

/* The pieces of the device's screens, in the LCD's ink (DeviceParts.swift). */
.screen-row { display: flex; align-items: center; gap: 10px; }
.screen-right { margin-left: auto; }
.screen-label { font-size: 12.5px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; }
.screen-sub { font-size: 11px; font-weight: 500; text-transform: uppercase; letter-spacing: 0.03em; color: var(--ink-soft); }
.screen-title { font-size: clamp(24px, 2.4vw, 32px); font-weight: 700; line-height: 1.1; }
.screen-text { font-size: 13px; line-height: 1.55; }
.screen-big { font-size: clamp(30px, 3vw, 40px); font-weight: 700; line-height: 1; letter-spacing: -0.01em; }
.screen-counters { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; padding-block: 6px 4px; }
.screen-counters div { display: grid; gap: 6px; }
.screen-light { width: 9px; height: 9px; border-radius: 50%; background: var(--glass-shade); flex: none; }
.screen-light-busy { animation: blink 0.8s steps(1) infinite; }
.is-seen .screen-light-busy { animation: blink 0.8s steps(1) 4 forwards; }
.is-seen .screen-light-busy, .is-on .screen-light { background: var(--ink); }

/* Twenty segments, lit left to right, as SetDetailView lights them. */
.segments { display: grid; grid-template-columns: repeat(20, minmax(0, 1fr)); gap: 3px; height: 16px; margin-block: 4px 2px; }
.segments i { background: var(--glass-shade); }
/* The visitor's own set took the screen over (js/site.js): the segments
   show their count, not the demo's. */
.is-seen[data-yours] .segments i:nth-child(n) { animation: none; background: var(--glass-shade); }
.is-seen[data-yours] .segments i:nth-child(n).is-lit { background: var(--ink); }
.is-seen .segments i:nth-child(-n + 17) { animation: segment 0.01s linear forwards; }
.is-seen .segments i:nth-child(1) { animation-delay: 0.25s; }
.is-seen .segments i:nth-child(2) { animation-delay: 0.39s; }
.is-seen .segments i:nth-child(3) { animation-delay: 0.53s; }
.is-seen .segments i:nth-child(4) { animation-delay: 0.67s; }
.is-seen .segments i:nth-child(5) { animation-delay: 0.81s; }
.is-seen .segments i:nth-child(6) { animation-delay: 0.95s; }
.is-seen .segments i:nth-child(7) { animation-delay: 1.09s; }
.is-seen .segments i:nth-child(8) { animation-delay: 1.23s; }
.is-seen .segments i:nth-child(9) { animation-delay: 1.37s; }
.is-seen .segments i:nth-child(10) { animation-delay: 1.51s; }
.is-seen .segments i:nth-child(11) { animation-delay: 1.65s; }
.is-seen .segments i:nth-child(12) { animation-delay: 1.79s; }
.is-seen .segments i:nth-child(13) { animation-delay: 1.93s; }
.is-seen .segments i:nth-child(14) { animation-delay: 2.07s; }
.is-seen .segments i:nth-child(15) { animation-delay: 2.21s; }
.is-seen .segments i:nth-child(16) { animation-delay: 2.35s; }
.is-seen .segments i:nth-child(17) { animation-delay: 2.49s; }
@keyframes segment { to { background: var(--ink); } }

/* The price history: a stepped line and nothing else, drawn in steps. */
.chart { width: 100%; height: auto; display: block; margin-block: 6px 4px; }
/* The total, as the app's Collection Value screen sets it: the largest thing on the glass. */
.worth { font-size: clamp(34px, 4vw, 52px); margin-top: 10px; font-variant-numeric: tabular-nums; }
.chart-line { fill: none; stroke: var(--ink); stroke-width: 3; stroke-linejoin: round; stroke-dasharray: 100; stroke-dashoffset: 100; }
.is-seen .chart-line { animation: chart 2.4s steps(24) 0.3s forwards; }
@keyframes chart { to { stroke-dashoffset: 0; } }
.chart-change { opacity: 0; }
.is-seen .chart-change { animation: show 0.01s linear 2.9s forwards; }
@keyframes show { to { opacity: 1; } }

/* The Duo: closed, the wall; open, the wall beside the inspector. */
.duo { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; height: 108px; perspective: 600px; margin-block: 4px; }
.duo-leaf { border: 2px solid var(--ink); border-radius: 8px; padding: 8px; display: grid; gap: 5px; }
.duo-left { grid-template-columns: repeat(3, 1fr); grid-auto-rows: 1fr; transform-origin: right center; }
.duo-left i { background: var(--ink); border-radius: 2px; }
.duo-right { align-content: start; opacity: 0; }
.duo-card { display: block; width: 36%; aspect-ratio: 63 / 88; background: var(--ink); border-radius: 3px; margin-bottom: 3px; }
.duo-line { display: block; height: 4px; width: 80%; background: var(--ink-soft); }
.duo-short { width: 50%; }
.is-seen .duo-left { animation: unfold 4s ease-in-out infinite; }
.is-seen .duo-right { animation: reveal 4s ease-in-out infinite; }
@keyframes unfold { 0%, 15% { transform: rotateY(150deg); } 45%, 80% { transform: rotateY(0deg); } 100% { transform: rotateY(150deg); } }
@keyframes reveal { 0%, 30% { opacity: 0; } 50%, 80% { opacity: 1; } 100% { opacity: 0; } }

/* What is on, and what is not. */
.switches { display: flex; flex-wrap: wrap; gap: 10px 28px; padding-block: 4px; }
.switches li { display: flex; align-items: center; gap: 8px; font-size: 12.5px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; color: var(--ink-soft); }
.switches li.is-on { color: var(--ink); }
.is-seen .switches li.is-on .screen-light { animation: blink 0.8s steps(1) 3; }


.lcd { background: var(--bezel); border-radius: 16px; padding: 6px; box-shadow: 0 1px 0 rgba(255, 255, 255, 0.16), 0 18px 40px rgba(60, 0, 6, 0.35); }
.lcd-glass {
    height: 100%;
    border-radius: 10px;
    padding: 20px 22px 22px;
    color: var(--ink);
    background: var(--glass) repeating-linear-gradient(to bottom, var(--glass-shade) 0 1px, transparent 1px 3px);
    display: grid; align-content: start; gap: 8px;
}
.entry-no { font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; }
.lcd-glass h3 { font-size: 21px; line-height: 1.2; font-weight: 700; }
.entry-facts { font-size: 11px; font-weight: 500; text-transform: uppercase; letter-spacing: 0.03em; color: var(--ink-soft); }
.entry-text { font-size: 13.5px; line-height: 1.6; margin-top: 4px; }
/* While an entry types itself, the letters still to come hold their place. */
.typed-rest { visibility: hidden; }

/* ---- Release ------------------------------------------------------------ */

.release { padding-block: var(--s7); }
.release-row { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: var(--s4); align-items: center; }
.release-icon { border-radius: 22.5%; display: block; box-shadow: 0 18px 50px rgba(214, 33, 41, 0.25); }
.release h2 { font-size: clamp(20px, 3vw, 34px); line-height: 1.2; margin-bottom: 12px; }
.release .quiet { margin-top: 10px; }
/* Live: the button, and beside it the same link as a code for an iPhone's
   camera, which is for people reading on a desktop; a phone can tap. */
.release-actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s4); margin-top: var(--s3); }
.release-qr { display: flex; align-items: center; gap: var(--s2); margin: 0; }
.release-qr img { display: block; width: 88px; height: 88px; padding: 6px; border-radius: 10px; background: var(--text); }
.release-qr figcaption { max-width: 16ch; }
@media (hover: none) { .release-qr { display: none; } }

/* ---- The seal: Kiradex's own card back, turned over once ----------------- */

.seal { display: grid; justify-items: center; gap: var(--s4); padding-block: var(--s6) var(--s7); perspective: 1200px; }
.seal-card {
    appearance: none; border: 0; padding: 0; background: none; cursor: pointer; display: block;
    width: clamp(120px, 15vw, 176px); aspect-ratio: 63 / 88; border-radius: 4.6% / 3.3%; position: relative;
    transform-style: preserve-3d;
    transform: rotateY(-180deg) rotate(-4deg);
    transition: transform 1.5s cubic-bezier(0.2, 0.9, 0.2, 1.05), translate 0.2s var(--ease);
    box-shadow: calc((0.5 - var(--lx)) * 34px) calc(18px + (0.5 - var(--ly)) * 22px) 44px rgba(0, 0, 0, 0.6);
}
/* Seen, it turns over once to its back. Pressed, it turns to its front and
   stays. Hovered, it only lifts: a hover never turns anything over. */
.seal-card.is-seen { transform: rotateY(0deg) rotate(-4deg); transition-duration: 1.5s, 0.2s; }
.seal-card.is-seen:hover { translate: 0 -6px; }
.seal-card.is-seen.is-front { transform: rotateY(180deg) rotate(4deg); transition-duration: 0.9s, 0.2s; }
.seal-card:focus-visible { outline: 2px solid var(--text); outline-offset: 6px; }
.seal-face { position: absolute; inset: 0; border-radius: inherit; overflow: hidden; backface-visibility: hidden; -webkit-backface-visibility: hidden; }
.seal-front { transform: rotateY(180deg); }
.seal-face svg { display: block; width: 100%; height: 100%; }
.seal-face::after {
    content: ""; position: absolute; inset: 0; background: var(--foil); background-size: 260% 260%;
    background-position: calc(100% - var(--lx) * 100%) calc(100% - var(--ly) * 100%); mix-blend-mode: screen; opacity: 0.7;
}
.seal-front::after { opacity: 0.35; }
.seal-name { font: 800 58px var(--mono); font-stretch: 112.5%; letter-spacing: 12px; fill: rgba(255, 255, 255, 0.92); }
/* The front, in the device's own lettering: the name on the shell, the entry on the LCD. */
.seal-title { font: 800 50px var(--mono); font-stretch: 112.5%; letter-spacing: 7px; fill: #fff; }
.seal-no { font: 700 24px var(--mono); fill: rgba(255, 255, 255, 0.85); }
.seal-kind { font: 700 19px var(--mono); font-stretch: 75%; letter-spacing: 2.5px; fill: #244d1f; }
.seal-text { font: 500 24px var(--mono); fill: #123317; }
.seal-fine { font: 700 18px var(--mono); font-stretch: 75%; letter-spacing: 2px; fill: rgba(255, 255, 255, 0.8); }
.seal-fine [lang="ja"] { font-family: var(--jp); font-weight: 700; letter-spacing: 0; }
.seal-line { font-size: 13.5px; color: var(--quiet); text-align: center; padding-inline: var(--gutter); }
/* The sign-off: キラDEX, the name as a Japanese brand would set it, katakana
   and Latin in one word. */
.seal-line .lockup { color: var(--text); font-weight: 800; font-stretch: 112.5%; letter-spacing: 0.12em; margin-right: 10px; }
.seal-line .lockup [lang="ja"] { font-weight: 700; font-size: 1.1em; letter-spacing: 0.02em; margin-right: 0.1em; }

/* The sound switch: off unless asked for. */
.sound-switch {
    appearance: none; background: none; border: 0; padding: 4px 0; cursor: pointer;
    font: 500 12.5px/1.4 var(--mono); font-stretch: 75%; color: var(--quiet);
    text-decoration: underline; text-decoration-color: color-mix(in srgb, currentColor 45%, transparent); text-underline-offset: 3px;
}
.sound-switch:hover, .sound-switch[aria-pressed="true"] { color: var(--text); }

/* ---- Support and privacy ------------------------------------------------ */

.page { padding-block: clamp(36px, 7vw, 84px) clamp(56px, 9vw, 112px); }
.page h1 {
    font-size: clamp(24px, 4vw, 40px); line-height: 1.2; font-weight: 700;
    margin: 10px 0 16px; text-wrap: balance;
}
.page .lede { margin-bottom: 8px; }
.prose h2, .faq dt {
    font-stretch: 75%; text-transform: none; letter-spacing: 0;
    font-size: 16.5px; font-weight: 700; line-height: 1.4;
}
.prose h2 { margin: 34px 0 8px; }
.prose p, .prose li { color: var(--quiet); max-width: 68ch; }
.prose p + p { margin-top: 10px; }
.prose ul { display: grid; gap: 10px; margin-bottom: 12px; }
.prose li { padding-left: 18px; position: relative; }
.prose li::before { content: ""; position: absolute; left: 0; top: 0.72em; width: 6px; height: 6px; border-radius: 50%; background: var(--red); }
.prose strong { color: var(--text); font-weight: 700; }

.faq { margin-top: 30px; border-top: 1px solid var(--line); }
.faq > div { padding: 20px 0; border-bottom: 1px solid var(--line); display: grid; gap: 6px; }
.faq dd { color: var(--quiet); max-width: 68ch; }

/* ---- Footer ------------------------------------------------------------- */

.foot { border-top: 1px solid var(--line); padding-block: var(--s5) var(--s6); }
.foot-grid { display: grid; grid-template-columns: minmax(200px, 1fr) minmax(0, 2.4fr); gap: 24px clamp(24px, 5vw, 72px); }
.foot .brand { margin-bottom: 10px; }
.foot .quiet + .quiet { margin-top: 4px; }

/* ---- The set pages: the device open on one set, and its sheet beneath ----
   /sets lists every set by series; /sets/<id> is one set's facts, the cards
   to see first, and the sets either side of it. */
.sheet { padding-block: var(--s7); position: relative; }
.sheet .letter-head { padding-right: 0; }
.sheet .eyebrow a { color: inherit; }
.sheet-cards { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--s4); max-width: 760px; }
.sheet-nav {
    display: flex; justify-content: space-between; gap: var(--s3);
    margin-top: var(--s6); padding-top: var(--s3); border-top: 1px solid var(--line);
    font-size: 13.5px; color: var(--quiet);
}
.sheet-nav a { text-decoration: none; color: var(--quiet); }
.sheet-nav a:hover { color: var(--text); }
.sheet-nav a[rel="next"] { text-align: right; }
.sheet-nav b { display: block; color: var(--text); font-weight: 700; margin-top: 2px; }
.series { margin-top: var(--s6); scroll-margin-top: var(--s4); }
.series h3, .series h4, .roster-block h3 {
    display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--s2) var(--s3);
    font-stretch: 112.5%; font-weight: 800; text-transform: uppercase; letter-spacing: 0.08em;
    font-size: clamp(17px, 2vw, 24px); line-height: 1.2;
}
.series h4[lang="ja"] { font-stretch: normal; font-weight: 700; letter-spacing: 0.04em; text-transform: none; }
.series .era-facts, .roster-block .era-facts, .run-title .era-facts { font-family: var(--mono); font-weight: 500; letter-spacing: 0.03em; }
/* A print run on the index: English, then Japanese. */
.run { margin-top: var(--s7); scroll-margin-top: var(--s4); }
.run:first-of-type { margin-top: 0; }
.run-title {
    display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--s2) var(--s3);
    font-size: clamp(22px, 3.4vw, 40px); line-height: 1.1; font-weight: 800; font-stretch: 112.5%;
    text-transform: uppercase; letter-spacing: 0.1em;
    padding-bottom: var(--s3); border-bottom: 1px solid var(--line);
}
.run-title [lang="ja"] { font-weight: 500; letter-spacing: 0.04em; color: var(--quiet); font-size: 0.6em; }
.sheet-title-ja { font-stretch: normal; letter-spacing: 0.04em; text-transform: none; font-weight: 700; }
/* Every card in the set, by number: a printer's checklist, in columns. */
.roster-block { margin-top: var(--s6); }
.roster { columns: 240px; column-gap: var(--s4); margin-top: var(--s3); font-size: 13.5px; }
.roster li { break-inside: avoid; display: flex; gap: var(--s2); padding-block: 5px; border-top: 1px solid var(--line); color: var(--text); }
.roster-no { flex: none; min-width: 4.5ch; color: var(--quiet); font-family: var(--mono); font-variant-numeric: tabular-nums; }
/* Every illustrator: a letter to jump to, then each name beside one of their cards. */
.letters { display: flex; flex-wrap: wrap; gap: 2px; margin-top: var(--s3); }
.letters a {
    min-width: 44px; min-height: 44px; display: inline-grid; place-items: center;
    text-decoration: none; font-weight: 700; color: var(--quiet); border-radius: 8px;
}
.letters a:hover { color: var(--text); background: rgba(243, 240, 235, 0.08); }
.names { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 260px), 1fr)); gap: var(--s3) var(--s4); margin-top: var(--s3); }
.name { display: grid; grid-template-columns: 64px minmax(0, 1fr); gap: var(--s2); align-items: center; padding-top: var(--s2); border-top: 1px solid var(--line); }
.name-name { font-weight: 700; font-size: 14.5px; line-height: 1.3; overflow-wrap: anywhere; }
.name-name [lang="ja"], .artist-ja { display: block; font-weight: 500; font-size: 12.5px; color: var(--quiet); letter-spacing: 0.04em; text-transform: none; font-stretch: normal; margin-top: 2px; }
.artist-ja { font-size: 13px; margin-top: 4px; }
.name-blank { display: block; aspect-ratio: 63 / 88; border-radius: 4.6% / 3.3%; box-shadow: 0 0 0 1px var(--line) inset; }
.name-name a { color: inherit; text-decoration: none; }
.name-name a:hover { text-decoration: underline; }
.artist h3 a { color: inherit; text-decoration: none; }
.artist h3 a:hover { text-decoration: underline; }
/* One illustrator: every card the name is on, set by set, newest first. */
.drawn { margin-top: var(--s5); }
.drawn h3 { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--s1) var(--s3); font-size: 15px; font-weight: 700; padding-bottom: var(--s2); border-bottom: 1px solid var(--line); }
.drawn h3 a { color: inherit; text-decoration: none; }
.drawn h3 a:hover { text-decoration: underline; }
.drawn .era-facts { font-weight: 500; }
.drawn-cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(clamp(84px, 11vw, 132px), 1fr)); gap: var(--s2); margin-top: var(--s3); }
/* Cards the catalog has no picture of: their numbers and names, as a line of text. */
.drawn-unseen { margin-top: var(--s2); font-size: 13px; line-height: 1.7; color: var(--quiet); max-width: 90ch; }
.drawn-unseen b { color: var(--text); font-weight: 500; }
/* Where the letter leads on to: all the names, all the sets. */
.more { display: flex; flex-wrap: wrap; gap: var(--s2); margin-top: var(--s6); }
/* The index, as the app's Dex shows it by default: a tile per set, its three
   chase cards fanned in a window, the most valuable in front. */
.set-tiles { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 280px), 1fr)); gap: var(--s3); margin-top: var(--s3); }
.set-tile {
    display: grid; gap: 4px; padding: var(--s2) var(--s2) var(--s3); border-radius: 18px;
    text-decoration: none; color: var(--text);
    background: linear-gradient(160deg, #14161a, #0b0c0f); box-shadow: 0 0 0 1px var(--line) inset;
    transition: translate 0.2s var(--ease), box-shadow 0.2s var(--ease);
}
.set-tile:hover { translate: 0 -3px; box-shadow: 0 0 0 1px rgba(243, 240, 235, 0.3) inset; }
.set-name { font-weight: 700; font-size: 15px; line-height: 1.3; margin-top: var(--s2); padding-inline: 6px; overflow-wrap: anywhere; }
.set-tile .era-facts { padding-inline: 6px; }
.chase {
    position: relative; display: grid; place-items: center; aspect-ratio: 16 / 10; overflow: hidden; border-radius: 12px;
    background: radial-gradient(70% 90% at 50% 60%, rgba(214, 33, 41, 0.22), transparent 72%), #0b0c0f;
}
.chase img { grid-area: 1 / 1; width: 34%; height: auto; border-radius: 4.6% / 3.3%; box-shadow: 0 8px 22px rgba(0, 0, 0, 0.55); }
.chase img:nth-child(1) { z-index: 3; }
.chase img:nth-child(2) { z-index: 2; translate: -68% 5%; rotate: -10deg; }
.chase img:nth-child(3) { z-index: 1; translate: 68% 5%; rotate: 10deg; }
/* No pictures in the catalog: the window stays, with two outlined cards in it. */
.chase-none::before, .chase-none::after {
    content: ""; grid-area: 1 / 1; width: 22%; aspect-ratio: 63 / 88; border-radius: 6% / 4.3%;
    box-shadow: 0 0 0 1.5px var(--line) inset;
}
.chase-none::before { translate: -22% 4%; rotate: -8deg; }
.chase-none::after { translate: 22% -2%; rotate: 6deg; }
.sheet-label { font-size: 12.5px; font-weight: 500; color: var(--quiet); letter-spacing: 0.02em; margin-bottom: var(--s2); }

.missing { min-height: 70svh; display: grid; place-items: center; text-align: center; }
.missing h1 { margin-block: 10px 18px; }

/* ---- Narrow ------------------------------------------------------------- */

@media (max-width: 760px) {
    .hero-field { min-height: clamp(420px, 66svh, 640px); }
    .hero-foot { grid-template-columns: 1fr; align-items: start; }
    .hero-actions { justify-items: start; }
    .foot-grid { grid-template-columns: 1fr; }
    /* On a phone the prop takes a line of its own above the words. */
    .prop, .prop-wide { position: static; translate: none; width: 170px; aspect-ratio: 1; margin: 0 auto 6px; }
    .prop-wide { width: 240px; aspect-ratio: 3 / 2; }
    .letter-head, .shell-head, .release-row { padding-right: 0; }
    .release-row .prop-wide { grid-column: 1 / -1; }
    .bank > li { grid-column: 1 / -1 !important; grid-row: auto !important; }
    .binder { grid-auto-columns: 88vw; }
    .era { grid-template-columns: 1fr; align-content: start; min-height: 0; }
    .fan { min-height: 0; padding-block: 18px 8px; grid-column: 1; grid-row: 1; }
    .pack { grid-column: 1; grid-row: 1; width: clamp(170px, 52vw, 230px); }
    .pack-note { grid-row: 2; align-self: start; text-align: center; }
    .fan li { width: clamp(104px, 31vw, 150px); }
    .ruler { grid-template-columns: minmax(0, 1fr); }
    .ruler-step { display: none; }
    .release-row { grid-template-columns: 1fr; }
    .release-icon { width: 72px; height: 72px; }
    /* The hands as a binder of their own: one name a page, four cards two
       by two, the next page showing at the edge. Eight stacked rows were
       a quarter of the page on a phone. */
    .artists {
        grid-template-columns: none; grid-auto-flow: column; grid-auto-columns: 78vw; gap: var(--s3);
        overflow-x: auto; overscroll-behavior-x: contain; scroll-snap-type: x mandatory;
        scrollbar-width: none;
        margin-inline: calc(-1 * var(--gutter)); padding-inline: var(--gutter); scroll-padding-inline: var(--gutter);
        padding-bottom: var(--s2);
    }
    .artists::-webkit-scrollbar { display: none; }
    .artist { scroll-snap-align: start; }
    .row { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s2); }
    /* Four hundred sets and a thousand cards are long lists on a phone: two
       tiles across, four cards across. */
    .set-tiles { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s2); }
    .set-tile { padding: 8px 8px var(--s2); border-radius: 14px; }
    .set-name { font-size: 13px; margin-top: 8px; padding-inline: 2px; }
    .set-tile .era-facts { padding-inline: 2px; font-size: 10.5px; }
    .drawn-cards { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 8px; }
    .names { gap: var(--s2); }
    .name { grid-template-columns: 48px minmax(0, 1fr); padding-top: 10px; }
}

@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after { transition-duration: 0.01ms !important; animation: none !important; }
    .readout[data-state="busy"] .readout-light { background: var(--ink); }
    .tcg-card { transform: none; }
    .binder { scroll-behavior: auto; }
    .dust { display: none; }
    .pack { rotate: none; }
    [data-seal="opening"] .pack-top, [data-seal="opening"] .pack-body { transform: none; }
    :root[data-companion="on"] .stage { animation: none; }
    .seal-card { transform: rotate(-4deg); }
    .seal-card.is-seen.is-front { transform: rotateY(180deg) rotate(4deg); }
    .segments i:nth-child(-n + 17), .screen-light-busy { background: var(--ink); }
    .chart-line { stroke-dashoffset: 0; }
    .chart-change, .duo-right { opacity: 1; }
    .duo-left { transform: none; }
}
