/* =========================================================================
   access.css — physical access control pages and the interactive demo lab.
   Layers on top of base.css; reuses its tokens rather than redefining them.
   Colour carries state: green means granted, red means denied, amber means
   degraded or offline. Nothing else in here is allowed to use those hues.
   ========================================================================= */

:root {
  --state-ok: #34d399;
  --state-deny: #f87171;
  --state-warn: #fbbf24;
  --state-ok-bg: rgba(52, 211, 153, 0.12);
  --state-deny-bg: rgba(248, 113, 113, 0.12);
  --state-warn-bg: rgba(251, 191, 36, 0.12);
}

/* ---------- Shared page furniture ---------- */

.eyebrow {
  display: inline-block;
  font-size: .78rem;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--accent-cyan);
  margin-bottom: var(--space-1);
}

.lead {
  font-size: clamp(1.05rem, 1.6vw, 1.2rem);
  max-width: 62ch;
}

.section-head { margin-bottom: var(--space-4); }
.section-head p { max-width: 68ch; }

.pill-row { display: flex; flex-wrap: wrap; gap: var(--space-1); margin-top: var(--space-2); }

.pill {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 5px 12px; border-radius: 999px;
  border: 1px solid var(--glass-border);
  background: var(--glass);
  font-size: .8rem; color: var(--text-secondary);
  white-space: nowrap;
}
.pill svg { width: 14px; height: 14px; color: var(--accent-cyan); }
.pill-ok   { color: var(--state-ok);   border-color: rgba(52,211,153,.35);  background: var(--state-ok-bg); }
.pill-warn { color: var(--state-warn); border-color: rgba(251,191,36,.35);  background: var(--state-warn-bg); }
.pill-deny { color: var(--state-deny); border-color: rgba(248,113,113,.35); background: var(--state-deny-bg); }

.callout {
  border-left: 3px solid var(--accent-cyan);
  background: var(--glass);
  border-radius: 0 var(--radius-md) var(--radius-md) 0;
  padding: var(--space-2) var(--space-3);
  margin-block: var(--space-3);
}
.callout h3 { color: var(--text-primary); }

/* ---------- Credential channel cards ---------- */

.chan-card {
  display: flex; flex-direction: column; gap: var(--space-1);
  transition: transform .2s ease, border-color .2s ease;
}
.chan-card:hover { transform: translateY(-3px); border-color: rgba(79,209,255,.45); }
.chan-card > svg { width: 34px; height: 34px; color: var(--accent-cyan); margin-bottom: var(--space-1); }
.chan-card .chan-tagline { color: var(--text-primary); font-weight: 600; font-size: .95rem; }
.chan-card .chan-reader { font-size: .78rem; letter-spacing: .06em; text-transform: uppercase; color: var(--accent-violet); font-weight: 700; }
.chan-card p { font-size: .92rem; }
.chan-card .pill-row { margin-top: auto; padding-top: var(--space-2); }

/* ---------- Spec definition lists ---------- */

.spec-list { display: grid; gap: 0; border-top: 1px solid var(--glass-border); }
.spec-row {
  display: grid; grid-template-columns: minmax(140px, 1fr) 2.4fr; gap: var(--space-2);
  padding: var(--space-2) 0; border-bottom: 1px solid var(--glass-border);
}
.spec-row dt { font-weight: 600; color: var(--text-primary); font-size: .92rem; }
.spec-row dd { color: var(--text-secondary); font-size: .92rem; }
@media (max-width: 620px) {
  .spec-row { grid-template-columns: 1fr; gap: 4px; }
}

/* ---------- Numbered step flow ---------- */

.steps { counter-reset: step; display: grid; gap: var(--space-2); margin-top: var(--space-3); }
.step {
  display: grid; grid-template-columns: 40px 1fr; gap: var(--space-2);
  align-items: start;
}
.step::before {
  counter-increment: step; content: counter(step);
  display: grid; place-items: center;
  width: 34px; height: 34px; border-radius: 50%;
  background: var(--gradient-accent); color: #06070a;
  font-weight: 800; font-size: .95rem;
}
.step h3 { font-size: 1.02rem; margin-bottom: 2px; }
.step p { font-size: .92rem; }

/* ---------- Product family cards ---------- */

.prod-card { display: flex; flex-direction: column; gap: var(--space-1); }
.prod-card > svg { width: 30px; height: 30px; color: var(--accent-violet); }
.prod-card h3 { margin-bottom: 0; }

/* =========================================================================
   The interactive demo lab
   ========================================================================= */

.lab {
  display: grid;
  grid-template-columns: minmax(280px, 360px) 1fr;
  gap: var(--space-3);
  align-items: start;
}
@media (max-width: 900px) { .lab { grid-template-columns: 1fr; } }

/* --- The reader mock-up --- */

.reader {
  background: linear-gradient(160deg, #14171f, #0a0c11);
  border: 1px solid var(--glass-border);
  border-radius: 28px;
  padding: 18px;
  box-shadow: 0 24px 60px rgba(0,0,0,.55);
  position: sticky; top: 90px;
}
@media (max-width: 900px) { .reader { position: static; } }

.reader-bezel {
  display: flex; align-items: center; justify-content: space-between;
  padding: 0 6px 12px;
}
.reader-brand { font-weight: 800; font-size: .82rem; letter-spacing: .12em; color: var(--text-secondary); }
.reader-lens { width: 10px; height: 10px; border-radius: 50%; background: #1f242f; box-shadow: inset 0 0 0 2px #0a0c11; }

.reader-screen {
  position: relative;
  aspect-ratio: 3 / 4;
  border-radius: 18px;
  background: #05070b;
  border: 1px solid rgba(255,255,255,.06);
  overflow: hidden;
  display: grid; place-items: center; text-align: center;
  padding: var(--space-2);
}

/* The screen state is driven by a data attribute so JS sets one thing. */
.reader-screen[data-state='idle']    { box-shadow: inset 0 0 60px rgba(79,209,255,.10); }
.reader-screen[data-state='reading'] { box-shadow: inset 0 0 70px rgba(139,107,255,.22); }
.reader-screen[data-state='granted'] { box-shadow: inset 0 0 80px rgba(52,211,153,.28); }
.reader-screen[data-state='denied']  { box-shadow: inset 0 0 80px rgba(248,113,113,.28); }

.reader-face { display: grid; gap: var(--space-1); justify-items: center; }
.reader-face svg { width: 64px; height: 64px; color: var(--accent-cyan); }
.reader-screen[data-state='granted'] .reader-face svg { color: var(--state-ok); }
.reader-screen[data-state='denied']  .reader-face svg { color: var(--state-deny); }
.reader-screen[data-state='reading'] .reader-face svg { color: var(--accent-violet); }

.reader-headline { font-weight: 700; font-size: 1.15rem; color: var(--text-primary); }
.reader-sub { font-size: .85rem; color: var(--text-secondary); }
.reader-holder { font-size: .8rem; color: var(--accent-cyan); font-weight: 600; }

/* Scan sweep, only while reading and only when motion is welcome. */
.reader-sweep {
  position: absolute; left: 0; right: 0; height: 2px;
  background: linear-gradient(90deg, transparent, var(--accent-violet), transparent);
  opacity: 0;
}
.reader-screen[data-state='reading'] .reader-sweep { animation: reader-sweep 1.1s ease-in-out infinite; }
@keyframes reader-sweep {
  0%   { top: 12%; opacity: 0; }
  20%  { opacity: 1; }
  80%  { opacity: 1; }
  100% { top: 88%; opacity: 0; }
}

.reader-statusbar {
  display: flex; align-items: center; justify-content: space-between;
  padding: 12px 6px 0; font-size: .74rem; color: var(--text-secondary);
}
.reader-dot { display: inline-flex; align-items: center; gap: 5px; }
.reader-dot::before {
  content: ''; width: 7px; height: 7px; border-radius: 50%; background: var(--state-ok);
}
.reader-dot[data-link='offline']::before { background: var(--state-warn); }

/* --- Controls --- */

.lab-controls { display: grid; gap: var(--space-3); }

.cred-tray { display: grid; grid-template-columns: repeat(auto-fit, minmax(124px, 1fr)); gap: var(--space-1); }

.cred-btn {
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  padding: 14px 10px; border-radius: var(--radius-md);
  background: var(--glass); border: 1px solid var(--glass-border);
  color: var(--text-primary); font-weight: 600; font-size: .82rem;
  cursor: pointer; text-align: center;
  transition: border-color .18s ease, transform .18s ease, background-color .18s ease;
  font-family: inherit;
}
.cred-btn svg { width: 24px; height: 24px; color: var(--accent-cyan); }
.cred-btn:hover:not(:disabled) { border-color: var(--accent-cyan); transform: translateY(-2px); }
.cred-btn:focus-visible { outline: 2px solid var(--accent-cyan); outline-offset: 2px; }
.cred-btn:disabled { opacity: .45; cursor: not-allowed; }
.cred-btn[aria-pressed='true'] { border-color: var(--accent-cyan); background: rgba(79,209,255,.10); }

/* --- Scenario switches --- */

.switch-row {
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-2);
  padding: var(--space-2) 0; border-bottom: 1px solid var(--glass-border);
}
.switch-row:last-child { border-bottom: none; }
.switch-row .switch-label { font-weight: 600; font-size: .92rem; color: var(--text-primary); }
.switch-row .switch-hint { font-size: .82rem; color: var(--text-secondary); }

.switch {
  position: relative; flex-shrink: 0;
  width: 46px; height: 26px; border-radius: 999px;
  background: rgba(255,255,255,.10); border: 1px solid var(--glass-border);
  cursor: pointer; padding: 0; font-family: inherit;
  transition: background-color .2s ease;
}
.switch::after {
  content: ''; position: absolute; top: 2px; left: 2px;
  width: 20px; height: 20px; border-radius: 50%;
  background: var(--text-secondary);
  transition: transform .2s ease, background-color .2s ease;
}
.switch[aria-checked='true'] { background: rgba(79,209,255,.28); border-color: var(--accent-cyan); }
.switch[aria-checked='true']::after { transform: translateX(20px); background: var(--accent-cyan); }
.switch:focus-visible { outline: 2px solid var(--accent-cyan); outline-offset: 2px; }

/* --- Event log --- */

.event-log { display: grid; gap: 8px; max-height: 340px; overflow-y: auto; padding-right: 4px; }
.event-log:empty::after {
  content: 'No events yet — present a credential to the reader.';
  color: var(--text-secondary); font-size: .88rem;
}

.event {
  display: grid; grid-template-columns: 4px 1fr auto; gap: var(--space-2); align-items: center;
  padding: 10px 12px; border-radius: 10px;
  background: rgba(255,255,255,.03); border: 1px solid var(--glass-border);
  font-size: .85rem;
}
.event .event-bar { width: 4px; height: 100%; border-radius: 2px; background: var(--text-secondary); }
.event[data-result='granted'] .event-bar { background: var(--state-ok); }
.event[data-result='denied']  .event-bar { background: var(--state-deny); }
.event[data-result='queued']  .event-bar { background: var(--state-warn); }
/* Informational rows — a holder change or a link state change is not a door
   decision, so it must not borrow the green that means "granted". */
.event[data-result='info']    .event-bar { background: var(--accent-cyan); }
.event-what { color: var(--text-primary); font-weight: 600; }
.event-why { color: var(--text-secondary); font-size: .8rem; }
.event-time { color: var(--text-secondary); font-size: .75rem; font-variant-numeric: tabular-nums; white-space: nowrap; }

/* --- The live dynamic-QR panel --- */

.qr-live { display: grid; gap: var(--space-2); justify-items: center; text-align: center; }

.qr-ring { position: relative; width: 220px; height: 220px; display: grid; place-items: center; }
.qr-ring svg.qr-ring-track { position: absolute; inset: 0; transform: rotate(-90deg); }
.qr-ring circle { fill: none; stroke-width: 6; }
.qr-ring .ring-bg { stroke: rgba(255,255,255,.08); }
.qr-ring .ring-fg { stroke: var(--accent-cyan); stroke-linecap: round; transition: stroke-dashoffset .95s linear, stroke .3s ease; }
.qr-ring[data-expiring='true'] .ring-fg { stroke: var(--state-warn); }

.qr-canvas {
  width: 168px; height: 168px;
  background: #f4f5f7; border-radius: 12px; padding: 10px;
  display: grid; place-items: center;
}
.qr-canvas svg { width: 100%; height: 100%; }

.qr-meta { font-size: .82rem; color: var(--text-secondary); }
.qr-token { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: .74rem; color: var(--accent-violet); word-break: break-all; max-width: 34ch; }
.qr-countdown { font-variant-numeric: tabular-nums; font-weight: 700; color: var(--text-primary); }

/* --- Small tabular readouts --- */

.readout { display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: var(--space-2); }
.readout-item { text-align: center; }
.readout-item .readout-value { font-size: 1.6rem; font-weight: 800; color: var(--text-primary); font-variant-numeric: tabular-nums; }
.readout-item .readout-label { font-size: .78rem; color: var(--text-secondary); }

/* --- Matrix tweaks --- */
.matrix-yes { color: var(--state-ok); font-weight: 700; }
.matrix-no  { color: var(--text-secondary); }

/* --- Honesty note under the demo --- */
.demo-note {
  font-size: .82rem; color: var(--text-secondary);
  border: 1px dashed var(--glass-border); border-radius: var(--radius-md);
  padding: var(--space-2); margin-top: var(--space-3);
}

@media (prefers-reduced-motion: reduce) {
  .reader-screen[data-state='reading'] .reader-sweep { animation: none; opacity: .6; top: 50%; }
  .cred-btn, .chan-card { transition: none; }
  .qr-ring .ring-fg { transition: none; }
}

/* Screen-reader-only text (table captions and skip labels). */
.visually-hidden {
  position: absolute !important;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%);
  white-space: nowrap; border: 0;
}

/* Architecture diagram used on the access-control pillar page. */
.arch-diagram { width: 100%; height: auto; }
.arch-diagram .arch-box { fill: rgba(255,255,255,.04); stroke: rgba(255,255,255,.14); stroke-width: 1; }
.arch-diagram .arch-box-accent { fill: rgba(79,209,255,.10); stroke: rgba(79,209,255,.45); }
.arch-diagram .arch-label { fill: #f4f5f7; font-size: 13px; font-weight: 600; text-anchor: middle; font-family: var(--font-sans); }
.arch-diagram .arch-sub { fill: #a3a8b4; font-size: 10.5px; text-anchor: middle; font-family: var(--font-sans); }
.arch-diagram .arch-link { stroke: rgba(139,107,255,.55); stroke-width: 1.4; fill: none; }
.arch-diagram .arch-link-dashed { stroke-dasharray: 5 5; stroke: rgba(163,168,180,.45); }

/* Illustrations. The width/height attributes are kept on the <img> so the
   browser reserves the right box before decode (no layout shift), and
   height:auto lets the intrinsic ratio govern once it has one. Without this
   the declared pixel height wins on narrow screens and the art is stretched. */
.art {
  display: block;
  width: 100%;
  max-width: 760px;
  height: auto;
  margin: 0 auto;
}
figure { margin: 0; }
figure figcaption {
  text-align: center;
  color: var(--text-secondary);
  font-size: .85rem;
  margin-top: var(--space-1);
}

/* Wide diagrams carry ~10px labels. Scaled to a 327px phone they land at four
   pixels and become decoration. Same answer as .table-scroll: let the figure
   scroll inside itself at a legible minimum width, rather than shrinking the
   art until it says nothing. The page body never scrolls horizontally. */
.art-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.art-scroll .art { min-width: 640px; }
.art-scroll:focus-visible { outline: 2px solid var(--accent-cyan); outline-offset: 4px; }
@media (min-width: 800px) {
  .art-scroll .art { min-width: 0; }
}
