/* The door — a scanner screen for one hand, bright sun, and a moving queue.
 *
 * ── THE VERDICT IS THE SCREEN ──────────────────────────────────────────────────────────────
 *
 * The whole viewport carries the colour, not a badge inside a card. A marshal reads a colour
 * from arm's length in daylight; they do not read a sentence. The four outcomes are four
 * different colours on purpose — "already used" and "not a real ticket" call for different
 * reactions, and a UI that renders them the same has no security property left.
 *
 * ── CONTRAST IS MEASURED, NOT PICKED ───────────────────────────────────────────────────────
 *
 * Every verdict pairs #0C0C0E ink on a saturated ground, which is the same direction
 * tb_accent_ink() derives for the poster colours. Measured against #0C0C0E:
 *   green  #1FBF5B  8.6:1     amber #F5A623  10.6:1
 *   red    #FF3B30  5.3:1     idle  #15151A  (light ink, 15.2:1)
 * All clear 4.5:1 for body text and 3:1 for the large display line.
 */

.tb-door {
  min-height: 100vh;
  background: #0C0C0E;
  color: #F4F1EC;
  font-family: var(--tb-font);
  display: flex;
  flex-direction: column;
  padding-top: var(--nav-h, 72px);   /* the nav is position:fixed — every top-of-page pays */
}

.tb-door__bar {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  padding: 12px 16px; border-bottom: 1px solid rgba(244,241,236,.12);
}
.tb-door__event-label {
  font-size: 11px; letter-spacing: .18em; text-transform: uppercase; color: #B8B4AE;
}
.tb-door__event {
  flex: 1 1 auto; min-width: 0;          /* a <select> is sized by its longest OPTION */
  max-width: 100%;
  background: #15151A; color: #F4F1EC; border: 1px solid rgba(244,241,236,.2);
  padding: 9px 12px; font: inherit; font-size: 16px;   /* >=16px or iOS zooms on focus */
}
.tb-door__tally {
  font-family: var(--tb-heading-font, var(--tb-font));
  font-size: 20px; letter-spacing: .04em; color: #B8B4AE;
}

/* ── The verdict ── */
.tb-door__verdict {
  flex: 1 1 auto;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  text-align: center; padding: 32px 20px; min-height: 42vh;
  background: #15151A; color: #F4F1EC;
  transition: background .12s linear;
}
.tb-door__verdict[data-tone="ok"]   { background: #1FBF5B; color: #0C0C0E; }
.tb-door__verdict[data-tone="warn"] { background: #F5A623; color: #0C0C0E; }
.tb-door__verdict[data-tone="bad"]  { background: #FF3B30; color: #0C0C0E; }

.tb-door__headline {
  font-family: var(--tb-heading-font, var(--tb-font));
  font-size: clamp(44px, 13vw, 96px); line-height: .95;
  text-transform: uppercase; letter-spacing: .02em; margin: 0;
}
.tb-door__holder {
  font-size: clamp(18px, 5vw, 26px); font-weight: 600; margin: 14px 0 0;
}
.tb-door__detail {
  font-size: 14px; margin: 8px 0 0; opacity: .8;
  /* The code is long and must never push the screen sideways. */
  overflow-wrap: anywhere;
}

/* ── `hidden` MUST WIN. THIS IS WHY THE DOOR SHOWED A BLACK SCREEN. ─────────────────────────
   ⚠️ The `hidden` attribute is ONLY `display: none` in the user-agent stylesheet, so ANY author
   rule that sets `display` on the same element silently overrides it. Two rules here did:

     .tb-door__camera { display: grid }   -> the camera box rendered on a cold page, and
                                            `.tb-door__camera video { background: #000 }` is a
                                            BLACK RECTANGLE. Reported from a phone on 2026-09-06
                                            as "the camera does not open — black screen". It had
                                            never opened; that box was there the whole time.
     .tb-door__resume { display: block }  -> mine, added with the button's styling. The green
                                            "СЛЕДВАЩ" was visible from page load, before any
                                            scan, so pressing it correctly did nothing:
                                            resumeScanning() returns early when nothing is
                                            halted. Reported twice as "СЛЕДВАЩ does nothing".

   Fixed once, as a property, rather than by patching those two selectors — the next element that
   is toggled with `hidden` and styled with `display` would reintroduce it otherwise.

   ⚠️ AND IT IS WHY `el.hidden` IS NOT AN ASSERTION. Every measurement I made read the `hidden`
   PROPERTY, which was true and meaningless. Only a visibility check — Playwright's toBeHidden(),
   or a measured bounding box — can see this, and that assertion is what caught it. */
[hidden] { display: none !important; }

/* ── Controls ── */
.tb-door__controls { padding: 16px; display: grid; gap: 14px; }
.tb-door__scan, .tb-door__go, .tb-door__stop, .tb-door__resume {
  font-family: var(--tb-heading-font, var(--tb-font));
  font-size: 22px; letter-spacing: .06em; text-transform: uppercase;
  border: 0; padding: 16px 22px; cursor: pointer;
  background: #F4F1EC; color: #0C0C0E;
  /* 48px minimum target: this is used with gloves on. */
  min-height: 56px;
}
.tb-door__stop { background: transparent; color: #F4F1EC; border: 2px solid rgba(244,241,236,.35); }

/* ── "Следващ" ──────────────────────────────────────────────────────────────────────────────
   Shown while the camera is paused on a verdict, so it is the ONLY thing to press and it is
   pressed with gloves on, at arm's length, by someone with a queue in front of them. Full
   width and inside the verdict panel, because the answer and the way past it belong together
   — a marshal must not have to look elsewhere to clear the screen. */
.tb-door__resume {
  display: block; width: 100%; margin: 16px 0 0;
  background: #1FBF5B; color: #06210F;
}
.tb-door__resume:focus-visible { outline: 3px solid #F4F1EC; outline-offset: 3px; }
.tb-door__scan:focus-visible, .tb-door__go:focus-visible,
.tb-door__code:focus-visible { outline: 3px solid #1FBF5B; outline-offset: 3px; }

.tb-door__camera { display: grid; gap: 10px; }
.tb-door__camera video { width: 100%; max-height: 46vh; background: #000; object-fit: cover; }

.tb-door__manual label {
  display: block; font-size: 11px; letter-spacing: .18em;
  text-transform: uppercase; color: #B8B4AE; margin-bottom: 8px;
}
.tb-door__manual-row { display: grid; grid-template-columns: 1fr auto; gap: 10px; }
.tb-door__manual input[type="text"] {
  background: #15151A; color: #F4F1EC; border: 1px solid rgba(244,241,236,.2);
  padding: 14px; font: inherit; font-size: 18px; letter-spacing: .06em;
  text-transform: uppercase; min-width: 0;
}
.tb-door__peek {
  display: flex; align-items: center; gap: 9px; margin-top: 10px;
  text-transform: none; letter-spacing: 0; font-size: 14px; color: #C9C4BD;
}
.tb-door__peek input { width: 20px; height: 20px; accent-color: #1FBF5B; }

/* ── The running log ── */
.tb-door__log { list-style: none; margin: 0; padding: 0 16px 28px; }
.tb-door__log li {
  padding: 10px 0 10px 14px; border-bottom: 1px solid rgba(244,241,236,.1);
  font-size: 14px; color: #C9C4BD; position: relative; overflow-wrap: anywhere;
}
.tb-door__log li::before {
  content: ""; position: absolute; left: 0; top: 16px;
  width: 6px; height: 6px; border-radius: 50%;
}
.tb-door__log li[data-tone="ok"]::before   { background: #1FBF5B; }
.tb-door__log li[data-tone="warn"]::before { background: #F5A623; }
.tb-door__log li[data-tone="bad"]::before  { background: #FF3B30; }

.tb-door--denied { justify-content: center; }
.tb-door--denied .tb-door__wrap { padding: 40px 20px; text-align: center; }
.tb-door--denied a { color: #1FBF5B; }

/* The route section. Only LAYOUT here — every colour and every internal rule comes from
   components.css via the --tb-* contract set inline above. That is the point: this surface
   contributes a heading and some padding, and knows nothing else about the component. */
.tb-door__route { padding: 8px 16px 32px; }
.tb-door__route h2 {
  font-family: var(--tb-heading-font, var(--tb-font));
  font-size: 22px; letter-spacing: .05em; text-transform: uppercase;
  color: #B8B4AE; margin: 0 0 14px; font-weight: 400;
}
