* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

html, body {
  height: 100%;
  height: 100dvh; /* actual visible height on mobile, address bar and all */
}

body {
  background: #0f0f10;
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  /* This is a controller UI, not text — a mobile long-press on a button
     shouldn't select it or pop the copy/select callout. */
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
}

/* Only real-page addition on top of the Lab prototype — this page is
   reachable from the live portfolio (rogerioximba.com.br/playground),
   linked from the footer's RX icon, so it needs a way back. */
.back-link {
  position: fixed;
  top: 16px;
  left: 16px;
  font-size: 12px;
  color: #6b6b6b;
  text-decoration: none;
  z-index: 1;
}

.back-link:hover {
  color: #a9a9a9;
}

.stage {
  display: flex;
  align-items: center;
  justify-content: center;
}

/* Base shell — Figma node 178:1046 ("Frame 40399"), natural size
   350.4851 x 762, kept at exact Figma px so every fixed-size child layer
   (buttons, etc.) stays pixel-accurate. main.js scales the whole thing as
   one unit via `transform: scale()` to fit small viewports, instead of
   resizing the box itself — fluid width/aspect-ratio worked while .device
   was empty, but breaks fixed-px children the moment real content lands.

   box-shadow is a 3-layer bevel simulating the device's physical edge
   (light rim top, darker rim right/bottom) rather than a drop shadow.
   The lopsided padding (big on the right) reserves space along that edge
   for whatever sits there — assuming a side control, to confirm once
   that layer arrives.

   The flex layout (column, bottom-packed) is also straight from Figma:
   justify-content: flex-end stacks the children at the bottom, inset by
   the 13.95px bottom padding. align-items stays flex-start (Figma's
   value) as the default, but every child so far overrides it with its
   own align-self: center + a compensating margin-right (see .screen's
   comment) to center against the device's true width instead of its
   lopsided padding box. */
.device {
  width: 350.4851px;
  height: 762px;
  background: #242527;
  border-radius: 40px;
  box-shadow:
    0 0 0 0.174px #959698,
    0 0 0 0.872px #8c8d92,
    0 -0.872px 0 0.174px #e7e7e7;
  overflow: hidden;
  position: relative; /* anchors .title's absolute positioning below */
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  align-items: flex-start;
  gap: 8.719px;
  padding: 13.95px 59.286px 54px 13.95px;
}

/* Title — Figma nodes 203:188 ("Container") > 203:189 ("Heading 1") >
   203:190 (the text itself). Unlike every other piece so far, this one
   IS given as absolute coordinates in Figma (left:17px, top:31px) rather
   than flowing through .device's own auto-layout — confirms the earlier
   suspicion that children in this file are individually positioned, not
   actually laid out by .device's flex rules. position:absolute takes it
   out of the flex flow entirely, so it doesn't affect the bottom-packed
   .screen/.controls/.select-btn group.
   opacity:60% and cursor:pointer on the <a> suggest this might double as
   the PRD's "back to menu" control, but no href/behavior is wired yet —
   it's just the title for now. */
.title {
  position: absolute;
  left: 17px;
  top: 31px;
  width: 222.323px;
  height: 34.874px;
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  padding: 0 17.437px;
  opacity: 0.6;
  cursor: pointer;
  text-decoration: none;
}

.title-heading {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  flex: 1 0 0;
  min-width: 1px;
}

.title-text {
  align-self: stretch;
  color: #b1b7bd;
  font-family: 'Inter', sans-serif;
  font-size: 15.693px;
  font-style: italic;
  font-weight: 700;
  line-height: 34.787px;
  letter-spacing: -0.872px;
  text-transform: uppercase;
  text-align: left;
}

/* Button bar — Figma node 208:237. Sits inside .device via the flex rules
   above; flex-shrink: 0 keeps it at its true 320x190 instead of getting
   squeezed by the parent's flex layout. */
.controls {
  display: flex;
  align-self: center; /* see .screen's comment — compensates .device's lopsided padding */
  margin-right: -45.336px;
  width: 320px;
  height: 190px;
  padding: 5px;
  align-items: flex-start;
  gap: 5px;
  border-radius: 8px;
  background: #090a0f;
  flex-shrink: 0;
}

/* Buttons — Figma nodes 178:1179 (normal) / 178:1188 (pressed). .pressed
   is toggled from main.js via pointer events rather than relying on
   :active, which is unreliable on touch without a listener in the chain. */
.dpad-btn {
  display: flex;
  width: 152.5px;
  height: 180px;
  padding: 20px;
  align-items: flex-start;
  gap: 10px;
  border: 0;
  border-radius: 4px;
  background: #242527;
  box-shadow:
    0.5px 0 2px 0.1px #47474d,
    0 -1px 1px 0.1px #e7e7e7;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
}

.dpad-btn.pressed {
  background: #1a1a1b;
  box-shadow:
    0 4px 4px 0 rgba(0, 0, 0, 0.6) inset,
    0.5px 0 2px 0.1px #47474d;
}

/* Arrow — Figma node 208:243 ("Polygon 1"), one shared asset for both
   buttons (rotated 180deg for "down"). Its 28x28 box lands at (20,20) for
   free via .dpad-btn's own padding + align-items:flex-start; the SVG's
   real rendered size (21.3265x19) sits centered inside that box, matching
   the inset Figma reported around the raw polygon shape. */
.dpad-icon {
  width: 28px;
  height: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
  mix-blend-mode: plus-lighter;
  pointer-events: none;
  transition: opacity 0.12s ease;
}

.dpad-btn.pressed .dpad-icon {
  opacity: 0.28;
}

.dpad-icon img {
  display: block;
  width: 21.3265px;
  height: 19px;
}

.dpad-btn--down .dpad-icon {
  transform: rotate(180deg);
}

/* Select/confirm button — turns out to be 4 layers, not 3: node 187:1649
   ("Component 4") is a dark #090a0f wrapper (radius 16, padding 4.359px)
   that the orange bar (211:254 / 181:1193 "base" / 181:1194 "top") sits
   inside — same dark tone as .controls. Missed this outer layer at first;
   .select-btn IS that wrapper now, and .select-btn-base fills it via
   flex: 1 instead of a fixed size (which is what produces the exact same
   67.2814px height Figma reports, just expressed as 76 - 2*4.359 instead
   of a hardcoded number). Placement within .device (stacked under
   .controls) is still a best guess pending real coordinates — same open
   question as .controls.

   Pressed state: 164:866 (base) / 164:867 (top). The top's shadow is
   identical pressed or not — only its background shifts; the base gains
   an inset dark shadow (the rim reading as pushed-in) on top of its own
   background/shadow change. .pressed is toggled from main.js, same
   pointer-event pattern as .dpad-btn. */
.select-btn {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  align-self: center; /* see .screen's comment — compensates .device's lopsided padding */
  margin-right: -45.336px;
  width: 328px;
  height: 76px;
  padding: 4.359px;
  border: 0;
  border-radius: 16px;
  background: #090a0f;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
  flex-shrink: 0;
}

.select-btn-base {
  display: flex;
  flex: 1 0 0;
  width: 100%;
  min-height: 0;
  justify-content: center;
  align-items: center;
  gap: 8.719px;
  overflow: hidden;
  border-radius: 12px;
  background: #ff7034;
  box-shadow:
    0.436px 0 1.744px 0.087px #47474d,
    0 -0.872px 0.872px 1px #feaf8e;
}

.select-btn-top {
  display: flex;
  width: 304px;
  height: 52px;
  padding: 10px;
  align-items: flex-start;
  gap: 10px;
  border-radius: 8px;
  background: #f47435;
  box-shadow:
    0 4px 4px 0 rgba(0, 0, 0, 0.4),
    0 -4px 4px 0.8px rgba(255, 255, 255, 0.2);
}

.select-btn.pressed .select-btn-base {
  background: #d95f2b;
  box-shadow:
    0.436px 0 1.744px 0.087px #47474d,
    0 4px 4px 0 rgba(0, 0, 0, 0.40) inset,
    0 -0.87px 0.87px 0 #aa5733;
}

.select-btn.pressed .select-btn-top {
  background: #ea6828;
}

/* Screen — Figma node 176:997, 6 concentric bevel layers (178:1097 outer
   black frame down to 178:1164 the actual content slot). Each layer insets
   the next by exactly its own padding, confirmed against the numbers
   Figma gave before building this:
     L1->L2 (333.561-329.561)/2 = 2      = L1 padding
     L2->L3 (329.561-315.611)/2 = 6.975  = L2 padding
     L3->L4 (315.611-301.661)/2 = 6.975  = L3 padding
     L4->L5 (301.661-285.661)/2 = 8      = L4 padding
     L5->L6  285.661 - 2*18.309 = 249.043 = L6 width
   .screen-content (L6) is an empty content slot for now — no game layers
   handed over for it yet. Placement within .device (stacked above
   .controls) is a best guess pending real coordinates — same open
   question as .controls/.select-btn. */
.screen {
  display: flex;
  align-items: center;
  align-self: center; /* .device left-aligns children by default; center just this one */
  /* align-self:center alone centers within .device's *content box*, which
     is off-center because of its lopsided padding (13.95px left, 59.286px
     right) — that shifted the screen ~14px left of true device-center.
     This margin cancels exactly that asymmetry (59.286 - 13.95 = 45.336)
     so centering math runs as if the padding were symmetric. */
  margin-right: -45.336px;
  gap: 10px;
  width: 333.561px;
  height: 351.87px;
  padding: 2px;
  border-radius: 10.69px;
  background: #090909;
  flex-shrink: 0;
}

.screen-bezel {
  display: flex;
  align-items: center;
  gap: 8.719px;
  width: 100%;
  height: 100%;
  padding: 6.975px;
  border-radius: 10.462px;
  background: #313131;
  box-shadow: 0 3.487px 3.487px 0.872px rgba(0, 0, 0, 0.8) inset;
}

.screen-inset {
  display: flex;
  align-items: flex-start;
  gap: 8.719px;
  width: 100%;
  height: 100%;
  padding: 6.975px;
  border-radius: 6.975px;
  background: #202020;
  box-shadow:
    0 -0.872px 0.349px 0 rgba(255, 255, 255, 0.8),
    0 1.744px 3.487px 3.487px rgba(0, 0, 0, 0.6);
}

.screen-ring {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 10px;
  width: 100%;
  height: 100%;
  padding: 8px;
  border-radius: 4px;
  background: conic-gradient(
    from 180deg at 50% 50%,
    rgba(131, 131, 131, 0.51) 43deg,
    rgba(34, 34, 34, 0.51) 45deg,
    rgba(32, 32, 32, 0.51) 132deg,
    rgba(4, 4, 4, 0.51) 136deg,
    rgba(0, 0, 0, 0.51) 180deg,
    rgba(5, 5, 5, 0.51) 225deg,
    rgba(32, 32, 32, 0.51) 228deg,
    rgba(34, 34, 34, 0.51) 315deg,
    rgba(131, 131, 131, 0.51) 316deg
  );
}

.screen-glass {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  align-items: center;
  width: 100%;
  height: 100%;
  padding: 17.437px 18.309px;
  border-radius: 3.487px;
  background: radial-gradient(63% 63% at 50% 50%, #0b0b0b 17.33%, #0c0c0c 68.73%, #010101 100%);
  box-shadow: 0 0 7.062px 15.693px rgba(0, 0, 0, 0.25) inset;
}

/* .screen-content now holds real content (176:1018's tree) instead of
   being an empty slot — switched align-items from flex-start to stretch
   and gap:4px to height:100%/justify-content:space-between, since the 3
   groups below (header, letter, options) are spaced by .screen-glass's
   own space-between distributing the leftover height between them, not a
   fixed 4px gap; the actual gaps read back at 14.75px and ~19px, matching
   whatever's left over after each group's own height, not a constant.

   Width note: 176:1018's own content row reports 265.0435px wide, ~16px
   wider than this shell's 249.044px content width (derived from L5's
   18.309px side padding on a 285.661px box). Built against the existing
   249.044px shell rather than resizing it — flag if that 16px gap turns
   out to matter visually. */
.screen-content {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  justify-content: space-between;
  width: 249.044px;
  height: 100%;
}

/* Group 1 — streak/record (178:1145 / 178:1147). Share Tech Mono, used
   throughout the screen's text except .screen-letter. */
.screen-header {
  display: flex;
  justify-content: space-between;
  width: 100%;
}

.screen-stat {
  font-family: 'Share Tech Mono', 'Courier New', monospace;
  font-size: 13.95px;
  line-height: 34.787px;
  letter-spacing: -1.7437px;
  color: #ffa84c;
}

.screen-stat--record {
  text-align: right;
}

/* Group 2 — the mystery letter (178:1149). Real Montserrat, loaded via
   Google Fonts in index.html <head>. */
.screen-letter {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 175px;
  font-family: 'Montserrat', sans-serif;
  font-size: 174.371px;
  line-height: 174.371px;
  color: #ffa84c;
  text-align: center;
  /* At this font-size, a descender (g/j/p/q/y) sits taller than the
     174.371px line-height and spills past .screen-letter's own box into
     .screen-options below (nothing here clips it). Rather than shrinking
     the letter or forcing extra headroom that would fight .screen-glass's
     justify-content:space-between, blend it against whatever it overlaps
     — an overlapping descender reads as an intentional inverted-glow
     effect instead of visual clipping/collision. */
  mix-blend-mode: difference;
}

/* Group 3 — the two font-name options (178:1155 poppins / 178:1160
   montserrat). Each row's icon slot stacks two inline SVGs (chevron +
   cross) in the same grid cell and shows exactly one via opacity:
     .screen-option--selected -> chevron (nav cursor, "playing" phase)
     .screen-option--correct  -> chevron, dark, on a filled green
                                  background (203:204/205's reveal state)
     .screen-option--wrong    -> cross, on the row the player actually
                                  picked when it wasn't the correct one
                                  (no Figma spec for this — new, own call)
   All three classes are toggled by main.js's render(). */
.screen-options {
  display: flex;
  flex-direction: column;
}

.screen-option {
  display: flex;
  align-items: center;
  gap: 8.719px;
  height: 35px;
  cursor: pointer; /* direct-select per PRD — still requires Confirm */
  transition: background-color 0.15s ease;
}

.screen-option--correct {
  background: #ffa84c;
}

.screen-option-icon {
  display: grid;
  place-items: center;
  width: 15.693px;
  height: 26.1556px;
  flex-shrink: 0;
  color: #ffa84c;
}

.screen-option-icon svg {
  grid-area: 1 / 1; /* stack both icons in the same cell */
  display: block;
  opacity: 0;
  transition: opacity 0.15s ease;
}

/* Rotated -90deg: the shape as exported is a down-chevron, this turns it
   into a right-pointing arrow aimed at the label next to it. */
.icon-chevron {
  width: 12.6419px;
  height: 7.41076px;
  transform: rotate(-90deg);
}

.icon-cross {
  width: 10px;
  height: 10px;
}

.screen-option--selected .icon-chevron {
  opacity: 1;
}

.screen-option--correct .icon-chevron {
  opacity: 1;
}

.screen-option--correct .screen-option-icon {
  color: #141414;
}

.screen-option--wrong .icon-cross {
  opacity: 1;
}

.screen-option-label {
  font-family: 'Share Tech Mono', 'Courier New', monospace;
  font-size: 17.437px;
  line-height: 34.787px;
  letter-spacing: -1.7437px;
  text-align: center;
  transition: color 0.15s ease;
  color: #ffa84c;
}

.screen-option--correct .screen-option-label {
  color: #141414;
}
