/* style.css -- SC-06 app shell / phone frame, SC-07 type tokens, SC-08/SC-13 band, SC-02/PL-14
   bubble, SC-09 loading state. Owned entirely by leaf-3.3 (game/style.css).

   No network at runtime (PLAN.md's shared contract): no @import, no Google Fonts link, no
   remote asset of any kind. Font stack is the neutral geometric grotesque system fonts already
   on the device, matching uniplay-design-system.md §2's "reads as a neutral geometric grotesque
   of the Inter / SF Pro class" note for when Gdgaio itself is unavailable.
*/

* { box-sizing: border-box; }

/* Type, 2026-09-03, CJ: "look for more premium fonts to use for the description". Aeonik is CJ's own brand
   face (the variable file from the portfolio, src/app/fonts). The serif for the floor number is Instrument
   Serif; Fraunces and Newsreader are also on disk so the card can be compared with ?serif=fraunces or
   ?serif=newsreader, and ?sans=system shows the old system stack. All self hosted: the game plays offline. */
@font-face { font-family: 'Aeonik'; src: url('./assets/fonts/AeonikVF.woff2') format('woff2'); font-weight: 100 900; font-display: swap; }
@font-face { font-family: 'Aeonik'; src: url('./assets/fonts/AeonikVF-Italic.woff2') format('woff2'); font-weight: 100 900; font-style: italic; font-display: swap; }
@font-face { font-family: 'Instrument Serif'; src: url('./assets/fonts/instrument-serif-latin.woff2') format('woff2'); font-weight: 400; font-display: swap; }
@font-face { font-family: 'Fraunces'; src: url('./assets/fonts/fraunces-latin.woff2') format('woff2'); font-weight: 300 700; font-display: swap; }
@font-face { font-family: 'Newsreader'; src: url('./assets/fonts/newsreader-latin.woff2') format('woff2'); font-weight: 300 600; font-display: swap; }

:root {
  /* The nacre, still: the five pastel blobs of ui/nacre.mjs at their mid drift, under the same milk, as CSS
     gradients. Painted wherever the animated SVG might not reach (the card's own background, and at a phone's
     width the root and the stage), so a band a phone shows past any box is the same ground, not a flat colour.
     CJ, 2026-09-03, on his iPhone, a third time: "Why is it white in the bottom here". */
  --nacre-base: #FDFCFB;
  --nacre-static:
    radial-gradient(circle 230px at 31% 26%, #FFE9EF 0%, rgba(255, 233, 239, 0) 100%),
    radial-gradient(circle 220px at 73% 34%, #E8F7F1 0%, rgba(232, 247, 241, 0) 100%),
    radial-gradient(circle 240px at 40% 63%, #EFEBFF 0%, rgba(239, 235, 255, 0) 100%),
    radial-gradient(circle 210px at 79% 83%, #FFF2E5 0%, rgba(255, 242, 229, 0) 100%),
    radial-gradient(circle 200px at 56% 46%, #E9F2FF 0%, rgba(233, 242, 255, 0) 100%);
  --font-sans: 'Aeonik', -apple-system, 'SF Pro Text', 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
  --font-serif: 'Instrument Serif', Georgia, 'Iowan Old Style', 'Times New Roman', serif;
}

html, body {
  margin: 0;
  height: 100%;
  font-family: var(--font-sans);
  color: #1A1A1A;
}

/* ============================================================================================
   SC-07 -- shared type scale. Verbatim from uniplay-design-system.md §2 / ASSET-MANIFEST SC-07:
   h1-h6, body, caption, label, number. Weight 400 everywhere, hierarchy from SIZE ALONE, never
   weight or colour. Tracking tightens with size (-0.04em headline down to -0.02em body) except
   `label`, which INVERTS to +0.01em, and `number`, which goes further negative to -0.05em.

   The design system's sizes are fluid clamps (e.g. h1: 2.625rem -> 6rem across a 20rem-90rem
   viewport). This game's frame is a FIXED phone-shaped box that never itself resizes (SC-06) --
   viewport-relative clamp() would size type against the real browser viewport, not against the
   frame's own (possibly letterboxed-down) box, and would drift out of proportion with it. Every
   token below is therefore pinned to the design system's own MOBILE (min) value instead, which
   is what a permanently-phone-width frame actually calls for. */

.type-h1 { font-size: 2.625rem; font-weight: 400; letter-spacing: -0.04em; line-height: 1.05; }
.type-h2 { font-size: 2.375rem; font-weight: 400; letter-spacing: -0.04em; line-height: 1.05; }
.type-h3 { font-size: 2.125rem; font-weight: 400; letter-spacing: -0.03em; line-height: 1.05; }
.type-h4 { font-size: 1.9375rem; font-weight: 400; letter-spacing: -0.02em; line-height: 1.15; }
.type-h5 { font-size: 1.625rem; font-weight: 400; letter-spacing: -0.02em; line-height: 1.15; }
.type-h6 { font-size: 1.3125rem; font-weight: 400; letter-spacing: -0.02em; line-height: 1.2; }
.type-body { font-size: 1.0625rem; font-weight: 400; letter-spacing: -0.02em; line-height: 1.4; }
/* SC-08's "small body-scale token" for the band statement: the `body` token pinned to its own
   smaller end -- a body-scale size, deliberately small, not a distinct named token. */
.type-body-sm { font-size: 1.0625rem; font-weight: 400; letter-spacing: -0.02em; line-height: 1.4; }
.type-caption { font-size: 1.0625rem; font-weight: 400; letter-spacing: -0.02em; line-height: 1.4; }
.type-label { font-size: 0.8125rem; font-weight: 400; letter-spacing: 0.01em; line-height: 1; }
.type-number { font-size: 6rem; font-weight: 400; letter-spacing: -0.05em; line-height: 1; }

/* ============================================================================================
   SC-06 -- app shell and phone frame. A fixed vertical phone-shaped frame, centred, that never
   changes size or aspect regardless of device (SC-10: laptop or landscape LETTERBOXES the same
   fixed frame rather than blocking with a rotate-your-device message -- the artifact's actual
   first open is most likely a desktop email client). */

.stage-outer {
  position: fixed;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #EEF1F4; /* neutral page background, per SC-06's "Built from" */
  overflow: hidden;
}
@media (prefers-color-scheme: dark) {
  .stage-outer { background: #151515; }
}

.phone {
  /* Fixed native size. Letterboxing is a pure-CSS min() of three constraints: the native size
     itself, the viewport width, and the viewport height re-expressed at the native aspect
     ratio -- whichever is smallest wins on BOTH axes together, so the box always scales down
     uniformly (never distorting the 375:812 aspect) and never grows past its native size. */
  --phone-w: 375;
  --phone-h: 812;
  width: min(375px, 100vw, calc(100vh * 375 / 812));
  height: min(812px, 100vh, calc(100vw * 812 / 375));
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  position: relative;
  --page: #A8D2FB;      /* the floor's own page colour, set per floor by main.mjs; PL-13 sky until then */
  background: var(--page);
  border: 6px solid #101010;
  border-radius: 40px;
  overflow: hidden;
}

/* On a phone the frame IS the screen (CJ, 2026-09-03: "On mobile there is some margin on left and right. Is it
   possible to make it cover the screen and adapt to the resolution of the phone?"): no bezel, no radius, the full
   viewport, and the safe areas respected. The room scales with the width, the card and the room centre in what is
   left. Above 520 px wide the framed phone stays, since a laptop is not a phone. */
@media (max-width: 520px) {
  /* Whatever the phone shows past the frame (the browser's chrome, overscroll) is painted in the screen's own
     colour: main.mjs sets --ground to the nacre's cream under the start card and the reckoning, and to the floor's
     page colour in play. CJ, 2026-09-03: the intro "still does not cover the full height on mobile". */
  html { background-color: var(--ground, #101010); background-image: var(--ground-image, none); }
  .stage-outer { background-color: var(--ground, #101010); background-image: var(--ground-image, none); }
  /* The card and the reckoning pin themselves to the viewport too, so they do not depend on the frame's box. */
  .phone > .start, .phone > .reckoning { position: fixed; inset: 0; }   /* outranks the absolute rule below */
  /* Pinned to the visible viewport, not sized by viewport units: Safari's toolbar comes and goes, and a frame
     of 100vh or 100dvh left a strip under the splash and the result screen (CJ, 2026-09-03, on his phone). */
  .phone {
    position: fixed;
    inset: 0;
    width: auto;
    height: auto;
    border: 0;
    border-radius: 0;
    padding-top: env(safe-area-inset-top);
    padding-bottom: env(safe-area-inset-bottom);
  }
}

.status-bar {
  /* Out of the flow since 2026-09-03, so the card and the room centre in the whole frame, not in what the
     status bar leaves under it: the margin above the card equals the margin under the room. */
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 28px;
}

/* ============================================================================================
   SC-02 / PL-14 -- the dialogue bubble's zone, ABOVE the board. `overflow: hidden` is a hard
   structural guarantee, not just a style: however long a line runs, the bubble can never spill
   downward into the board's own box, which is what keeps "dialogue never overlaps the board"
   true by construction rather than by convention. */

/* Phase 5, 2026-09-03: the floor card. Above the room, on the page colour, no panel. Floor number in a
   serif per CJ's mock, then the setting and your role. Both spring in when a floor begins, the number first. */
/* CJ, 2026-09-03, on the frame: the card sat at the top and the room low, "quite distanced from one another".
   So the board is only as tall as the room needs (main.mjs sets --board-h from the room's measured screen
   box), the card sits directly above it, and the two share the frame's spare height as margin above and
   below: margin-top auto on the card, margin-bottom auto on the board, the pair centred between them. */
.floorcard {
  flex: 0 0 auto;
  margin-top: auto;
  padding: 22px 22px 16px;
}
.floorcard .band { background: transparent; padding: 0; }
/* CJ, 2026-09-03, third pass on the card: one face, Aeonik, at three voices. The heading is the floor in
   Medium and the setting in Italic beside it, the body a weight down in Light. No serif: Instrument Serif
   read squeezed at this size. The serif files stay on disk for ?serif=, which now only styles the floor
   word, so the comparison is still one reload away. */
.floorcard .band-eyebrow {
  font-family: var(--font-sans);
  font-weight: 500;
  font-size: 1.5rem;
  letter-spacing: -0.025em;
  line-height: 1.15;
  color: #1A1A1A;
  margin: 0 0 10px;
  opacity: 0;
}
.floorcard .band-setting {
  font-style: italic;
  font-weight: 400;
  letter-spacing: -0.015em;
  color: rgba(26, 26, 26, 0.62);
  margin-left: 0.42em;
}
.floorcard .band-statement {
  font-weight: 300;
  font-size: 1.22rem;
  line-height: 1.4;
  letter-spacing: -0.008em;
  color: #1A1A1A;
  max-width: 21em;
  opacity: 0;
}
.floorcard.is-in .band-eyebrow { animation: card-spring 460ms cubic-bezier(0.2, 0.9, 0.3, 1.2) forwards; }
.floorcard.is-in .band-statement { animation: card-spring 520ms cubic-bezier(0.2, 0.9, 0.3, 1.2) 260ms forwards; }
@keyframes card-spring {
  0%   { opacity: 0; transform: translateY(12px) scale(0.96); }
  60%  { opacity: 1; transform: translateY(-3px) scale(1.015); }
  82%  { transform: translateY(1px) scale(0.997); }
  100% { opacity: 1; transform: none; }
}

/* The bubble now lives inside the room, beside the speaker's head. main.mjs sets left and top every frame
   from the head's screen position, and the tail points at the head from whichever side has room. */
.bubble {
  position: absolute;
  left: 0;
  top: 0;
  max-width: 62%;
  width: max-content;
  z-index: 4;
  background: #FFFFFF; /* PL-14, pure white */
  color: #1A1A1A; /* PL-14 */
  border: none;
  box-shadow: none;
  border-radius: 8px; /* "~8pt radius at 1x phone scale", SC-02 */
  padding: 14px 16px;
  opacity: 0;
  pointer-events: none;
  transition: none; /* every frame of motion here is authored explicitly in bubble.mjs -- never
                        a browser-interpolated (eased) transition standing in for it */
}
.bubble.is-visible { opacity: 1; }
/* CJ, 2026-09-03, second note: "Chat bubbles are too large text, it needs to be smaller." The line is read
   beside a head that is 40 px tall, so it sits a step under the card's body size, and the bubble's padding
   and width come down with it so the box shrinks with the type. */
.bubble { max-width: 58%; padding: 10px 12px; border-radius: 10px; }
.bubble-text { margin: 0; white-space: pre-wrap; font-size: 0.8125rem; line-height: 1.38; letter-spacing: -0.005em; }
.bubble-tail {
  position: absolute;
  top: 50%;
  width: 0;
  height: 0;
  border-top: 8px solid transparent;
  border-bottom: 8px solid transparent;
  transform: translateY(-50%);
}
.bubble.tail-left .bubble-tail { left: -9px; border-right: 9px solid #FFFFFF; }    /* the head is to the left */
.bubble.tail-right .bubble-tail { right: -9px; border-left: 9px solid #FFFFFF; }   /* the head is to the right */
/* CJ, 2026-09-03, second pass: the bubble sits ABOVE the head, never on it, and the tail points down from the
   bubble's bottom left or bottom right corner, whichever is over the head. */
.bubble.tail-bl .bubble-tail,
.bubble.tail-br .bubble-tail {
  top: auto;
  bottom: -10px;
  transform: none;
  border-left: 8px solid transparent;
  border-right: 8px solid transparent;
  border-top: 10px solid #FFFFFF;
  border-bottom: 0;
}
.bubble.tail-bl .bubble-tail,
.bubble.tail-br .bubble-tail { left: calc(var(--tail-x, 24px) - 8px); }   /* main.mjs sets --tail-x at the head's x */

/* ============================================================================================
   the board -- the isometric stage mount. Owned by leaf-2.2/node-5 for its actual contents
   (the three.js canvas gets appended here); this file only owns its box, its PL-13 sky
   backdrop, and the SC-09 loading state that shows until that canvas exists. */

.board {
  flex: 0 0 auto;
  height: var(--board-h, 440px);
  margin-bottom: auto;
  position: relative;
  background: var(--page, #A8D2FB);
  overflow: hidden;
}

/* SC-09 -- loading state: the frame, populated, with none of the numeric or bar-style progress
   a meter would use. A single gently-pulsing brand-blue mark -- a circle, never a bar shape, no
   percentage anywhere near it. The no-meter discipline gets no loading-screen exception. */
.board-loading {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
}
.loading-mark {
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: #4CA7FF;
  animation: board-loading-pulse 1.6s ease-in-out infinite;
}
@keyframes board-loading-pulse {
  0%, 100% { opacity: 0.35; transform: scale(0.85); }
  50% { opacity: 1; transform: scale(1); }
}

/* ============================================================================================
   SC-08 / SC-13 -- the room context band, BELOW the board. Persists for the whole floor (never
   cleared on input); never a HUD (band.mjs enforces this structurally -- see its header). */

.band { flex: 0 0 auto; }

/* ============================================================================================
   phase 5 -- start.mjs and reckoning.mjs. Both mount a CHILD overlay into the existing #board
   element (leaf-ui may not edit index.html), which already carries `position: relative` above,
   so `position: absolute; inset: 0` here covers exactly #board's own box, never the upper-zone
   bubble strip or the band strip below it. Same PL-02 near-white ground as every other Uniplay
   surface, same three palette values used everywhere else in this file: #FCFCFC, #1A1A1A,
   #4CA7FF. z-index lifts either overlay above the board's own contents (loading mark, later the
   isometric canvas) without needing those layers to know an overlay exists. */

.start,
.reckoning {
  position: absolute;
  inset: 0;
  z-index: 5;
  background-color: var(--nacre-base);
  background-image: var(--nacre-static);
  padding: 24px 20px;
}

.start {
  text-align: center;
  overflow: hidden;
}
/* Oversized by 8% each way and clipped by the card, so no rounding or viewport quirk leaves a band of the card's
   own background at an edge. */
.start-nacre { position: absolute; inset: -8%; width: 116%; height: 116%; display: block; }
/* The name, centred in the card, two rows in the floor heading's face (CJ, 2026-09-03). The first row is the
   size of a floor heading and the second is the word that matters, larger and tighter. */
.start-title {
  position: absolute;
  left: 0;
  right: 0;
  top: 50%;
  transform: translateY(-50%);   /* the centre of the card, not the centre of what the foot leaves over */
  display: flex;
  flex-direction: column;
  align-items: center;
  color: #1A1A1A;
  font-family: var(--font-sans);
}
.start-title-top { font-weight: 500; font-size: 1.5rem; letter-spacing: -0.025em; line-height: 1.15; }
.start-title-name { font-weight: 500; font-size: 3.25rem; letter-spacing: -0.045em; line-height: 1.02; margin-top: 2px; }
.start-foot { position: absolute; left: 0; right: 0; bottom: 44px; }
.start-goal { color: #1A1A1A; margin: 0 0 8px; font-weight: 400; font-size: 1.125rem; letter-spacing: -0.015em; line-height: 1.3; }
.start-how { color: #4B5563; margin: 0 0 14px; font-size: 0.8125rem; }
.board, .board canvas { -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; }
.start-tap { color: #4CA7FF; margin: 0; }

.reckoning {
  overflow-y: auto;
  overflow-x: hidden;
  /* A column, so the button below can sit at the BOTTOM of the frame when the trace is short (CJ: "in the
     bottom"), and after the last row when ten rows overflow and the screen scrolls. */
  display: flex;
  flex-direction: column;
}

/* The proximity prompt (phase 5, ui/prompt.mjs): one label anchored to a thing in the room, naming what a
   tap on it does. Positioned by main.mjs in board pixels at the thing's own screen position; the transform
   centres it there and lifts it clear of the thing. The same paper surface and ink as the band. */
.prompt {
  position: absolute;
  transform: translate(-50%, -100%);
  background: #FCFCFC;
  color: #1A1A1A;
  border-radius: 6px;
  padding: 5px 9px;
  white-space: nowrap;
  pointer-events: none;   /* a tap goes to the room beneath it, never to the label */
  box-shadow: none;
  --fill: 0%;
  z-index: 3;             /* the label is created before the canvas, so without this the room paints over it */
}
.prompt.is-far { opacity: 0.55; }
.prompt .prompt-text { display: block; }
.prompt .prompt-hint { display: block; margin-top: 3px; font-size: 0.6875rem; letter-spacing: 0.02em; color: #4CA7FF; font-weight: 500; }
.prompt .prompt-hint[hidden] { display: none; }
/* The hold filling the label from the left, in the brand blue at low weight, so confirming an act is
   something the eye sees landing rather than a timer it has to trust. */
.prompt.is-filling {
  background: linear-gradient(90deg, rgba(76, 167, 255, 0.35) var(--fill), #FCFCFC var(--fill));
}

/* A screen you step into (phase 5, ui/screen.mjs): the register on floor 7. Covers the board like the
   reckoning, same paper, and its options are rows, not buttons. */
.screen {
  position: absolute;
  /* A sheet that hugs its rows, rising from the bottom of the board, the room still showing above it. CJ,
     2026-09-03, on the register: "we could also loose a bit of the margin bottom here, it is excessive",
     then "move to bottom". */
  inset: auto 0 0 0;
  max-height: 100%;
  border-radius: 18px 18px 0 0;
  box-shadow: 0 -12px 28px rgba(16, 16, 16, 0.14);
  z-index: 6;
  animation: sheet-up 320ms cubic-bezier(0.2, 0.9, 0.3, 1) both;   /* it slides up from the frame's bottom edge */
  background: #FCFCFC;
  color: #1A1A1A;
  padding: 28px 22px 24px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  overflow-y: auto;
}
@keyframes sheet-up { from { transform: translateY(100%); } to { transform: none; } }
.screen-eyebrow { color: #4CA7FF; }
.screen-title { margin: 0 0 6px; }
.screen-body { color: #1A1A1A; margin: 0 0 10px; }
.screen-options { display: flex; flex-direction: column; gap: 8px; margin-top: 8px; }
.screen-option {
  padding: 14px 16px;
  border: 1px solid #DCDCDC;
  border-radius: 8px;
  background: #FFFFFF;
  cursor: pointer;
  transition: background 120ms ease, border-color 120ms ease;
}
/* Hover and press states, CJ 2026-09-03. The row lifts to the brand blue at low weight; the press is one
   step firmer, so the finger sees the choice register before the screen goes. */
.screen-option:hover { background: #F2F7FD; border-color: #4CA7FF; }
.screen-option:active { background: #E3EFFC; border-color: #4CA7FF; }
/* Once a row is chosen (CJ, 2026-09-03, "feedback on my choice"): it holds the blue, the others step back, and
   the done line says what the register now reads. The sheet keeps this for CONFIRM_MS, then goes. */
.screen.is-done .screen-option { transition: opacity 180ms ease, background 180ms ease, border-color 180ms ease; }
.screen.is-done .screen-option:not(.is-chosen) { opacity: 0.38; }
.screen.is-done .screen-option.is-chosen { background: #E3EFFC; border-color: #4CA7FF; }
.screen-done { color: #4CA7FF; min-height: 1.4em; margin-top: 12px; opacity: 0; transition: opacity 220ms ease 120ms; }
.screen.is-done .screen-done { opacity: 1; }


/* ============================================================================================
   The reckoning as a tower (CJ, 2026-09-03: the list was "so damn boring"; the mock at game/qa/reckoningmock.html
   was approved with a black button). Over the pale drifting ground, the verdict, then ten floors stacked, each in
   its room's page colour; chips for what a floor added; the crossing outlined in red with its reason open; the
   button black with white text. */
.reckoning { padding: 0; background-color: var(--nacre-base); background-image: var(--nacre-static); }
.reckoning .nacre { position: absolute; inset: 0; width: 100%; height: 100%; }
.reckoning .reck-head { position: relative; text-align: center; padding: 40px 24px 6px; }
.reckoning .reck-eyebrow { font-size: 0.8125rem; letter-spacing: 0.02em; color: #6B7280; font-weight: 500; margin: 0 0 12px; }
.reckoning .outcome-word { font-weight: 500; font-size: 3rem; letter-spacing: -0.045em; line-height: 1; margin: 0; color: #1A1A1A; text-align: center; }
.reckoning .verdict { font-weight: 300; font-size: 1.125rem; letter-spacing: -0.01em; margin: 8px 0 0; color: #1A1A1A; text-align: center; }
.reckoning .tower { position: relative; margin: 14px 40px 0 30px; display: flex; flex-direction: column; gap: 4px; flex: 0 0 auto; }
.reckoning .row { display: flex; align-items: center; gap: 10px; }
.reckoning .num { width: 22px; text-align: right; font-weight: 500; font-size: 0.8125rem; color: #6B7280; }
.reckoning .block { flex: 1; height: 36px; border-radius: 9px; background: var(--c, #E5E7EB); display: flex; align-items: center; justify-content: space-between; padding: 0 12px; font-size: 0.875rem; font-weight: 500; letter-spacing: -0.01em; color: #1A1A1A; box-shadow: inset 0 -2px 0 rgba(0, 0, 0, 0.08); cursor: pointer; }
.reckoning .block.unbuilt { background: transparent; border: 1.5px dashed rgba(26, 26, 26, 0.28); box-shadow: none; color: rgba(26, 26, 26, 0.45); cursor: default; }
.reckoning .block.crossing { outline: 2px solid #E6573A; outline-offset: 2px; }
.reckoning .chip { font-size: 0.75rem; font-weight: 500; padding: 3px 8px; border-radius: 999px; background: rgba(26, 26, 26, 0.72); color: #FFFFFF; }
.reckoning .chip.is-empty { display: none; }
.reckoning .block.corrupt .chip { background: #E6573A; }
.reckoning .floor-reason { position: relative; margin: 2px 0 6px 32px; padding: 10px 12px; border-radius: 10px; background: rgba(255, 255, 255, 0.78); font-size: 0.8125rem; line-height: 1.35; font-weight: 300; color: #1A1A1A; }
.reckoning .floor-reason.is-closed { display: none; }
.reckoning .carried-in { margin-top: 6px; color: #4CA7FF; font-size: 0.75rem; font-weight: 500; }
.reckoning .foot { position: relative; margin: 14px 30px 0; font-size: 0.8125rem; line-height: 1.4; color: #4B5563; font-weight: 300; }
.reckoning .again-button {
  position: relative;
  display: block;
  flex: 0 0 auto;
  margin: 18px 16px 24px;
  margin-top: auto;
  padding: 16px 18px;
  text-align: center;
  border-radius: 12px;
  background: #1A1A1A;
  color: #FFFFFF;
  font-weight: 500;
  cursor: pointer;
  transition: background 120ms ease, transform 120ms ease;
}
.reckoning .again-button:hover { background: #2C323B; }
.reckoning .again-button:active { background: #000000; transform: translateY(1px); }
