/* KeyboardTesterOnline — Shared Tool Styles v3.0 */

.ktt-wrap {
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
    max-width: 1080px;
    margin: 0 auto;
    padding: 20px 14px;
    color: #1a1a2e;
}
.ktt-intro { font-size:14px; color:#555; margin:0 0 14px; line-height:1.55; }

/* ══════════════════════════════════════════════
   Scalable keyboard grid
   Every board is a CSS grid of quarter-units.
   --q  = one quarter unit, derived from the container's own width
   --g  = gap between quarter units
   1u key = 4 columns + 3 gaps, so all rows stay perfectly aligned.

   Sizing is pure CSS via container query units: 100cqw is the wrap's width, so
   --q solves exactly to the space available and the board can never overflow.
   No JavaScript is involved in the width, which means a stale or failed script
   can never clip keys off the right-hand edge. ktt-kb.js only fills in --q for
   browsers too old for container queries.
   ══════════════════════════════════════════════ */
/* Registering --q/--g as real lengths is required: an untyped custom property
   substituted into a grid track resolves to 0px instead of evaluating its
   min()/cqw arithmetic. @property makes them compute before substitution. */
@property --q { syntax: '<length>'; inherits: true; initial-value: 8px; }
@property --g { syntax: '<length>'; inherits: true; initial-value: 3px; }

.ktt-kb-wrap {
    width: 100%;
    margin: 18px 0;
    container-type: inline-size;
}

.ktt-kb {
    /* --qc (columns), --qr (rows) and --qmax are set per board, inline. */
    --g: clamp(1.5px, 0.35cqw, 4px);
    --q: min(var(--qmax), calc((100cqw - (var(--qc) - 1) * var(--g)) / var(--qc)));
    display: grid;
    gap: var(--g);
    width: max-content;
    max-width: 100%;
    margin: 0 auto;
    user-select: none;
    -webkit-user-select: none;
}

.kb-key {
    display: flex; flex-direction: column;
    align-items: center; justify-content: center;
    box-sizing: border-box; overflow: hidden;
    padding: 0 calc(var(--q) * 0.16);
    border: 1px solid #C8CDD8;
    border-radius: calc(var(--q) * 0.5);
    background: #F4F6FB;
    color: #33384a;
    font-size: calc(var(--q) * 1.22);
    font-weight: 600;
    line-height: 1.08;
    text-align: center;
    white-space: nowrap;
    box-shadow: 0 calc(var(--q) * 0.2) 0 #C3C9D9;
    transition: background .08s, border-color .08s, color .08s;
}
.kb-key .kb-sub { font-size:.84em; opacity:.72; }
.kb-key .kb-alt { font-size:.8em;  opacity:.6; }

.kb-key.active { background:#2ECC71; border-color:#27AE60; color:#fff; box-shadow:0 calc(var(--q)*0.2) 0 #1E8449; }
.kb-key.held   { background:#3B8BEB; border-color:#2980B9; color:#fff; box-shadow:0 calc(var(--q)*0.2) 0 #1A5276; }
.kb-key.missed { background:#E74C3C; border-color:#C0392B; color:#fff; box-shadow:0 calc(var(--q)*0.2) 0 #922B21; }
.kb-key.active .kb-sub, .kb-key.held .kb-sub, .kb-key.missed .kb-sub,
.kb-key.active .kb-alt, .kb-key.held .kb-alt, .kb-key.missed .kb-alt { opacity:.85; }

/* keys the browser can never see (fn, eject, Touch ID) */
.kb-key.kb-na { background:#EDEFF5; color:#A9B0C0; border-style:dashed; box-shadow:none; }

/* Num / Caps / Scroll lock indicator strip */
.kb-leds { display:flex; align-items:center; justify-content:center; gap:calc(var(--q)*1.4); }
.kb-led  { display:flex; flex-direction:column; align-items:center; gap:calc(var(--q)*0.25);
           font-size:calc(var(--q)*1.05); color:#9aa3b5; font-weight:600; }
.kb-led i { width:calc(var(--q)*0.9); height:calc(var(--q)*0.9); border-radius:50%;
            background:#DDE1EA; border:1px solid #C3C9D9; }
.kb-led.on   { color:#27AE60; }
.kb-led.on i { background:#2ECC71; border-color:#27AE60; box-shadow:0 0 calc(var(--q)*0.8) #2ECC71; }

/* ── Legacy inline key chips (ghosting combos) ── */
.ktt-key {
    display:inline-flex; align-items:center; justify-content:center;
    min-width:38px; height:34px; padding:0 9px;
    border:1.5px solid #C8CDD8; border-radius:6px;
    background:#F4F6FB; color:#333;
    font-size:12px; font-weight:600;
    box-shadow:0 2px 0 #C0C6D8; white-space:nowrap;
}

/* ── Stats Panel ── */
.ktt-panel {
    background:#F8F9FC; border:1px solid #E0E4EF;
    border-radius:10px; padding:18px 22px; margin:16px 0;
}
.ktt-stat-row { display:flex; gap:28px; flex-wrap:wrap; }
.ktt-stat     { display:flex; flex-direction:column; gap:2px; }
.ktt-stat label { font-size:11px; text-transform:uppercase; letter-spacing:.07em; color:#7F8C9A; }
.ktt-stat span  { font-size:22px; font-weight:700; color:#1a1a2e; }

/* ── Progress Bar ── */
.ktt-bar-wrap { background:#E8ECF2; border-radius:8px; height:14px; overflow:hidden; margin:10px 0; }
.ktt-bar-fill { height:100%; border-radius:8px; background:#3B8BEB; transition:width .3s; }

/* ── Buttons ── */
.ktt-btn {
    display:inline-flex; align-items:center; gap:6px;
    padding:9px 20px; border:none; border-radius:8px;
    font-size:14px; font-weight:600; cursor:pointer;
    transition:opacity .15s, transform .1s;
}
.ktt-btn:active   { transform:scale(.97); }
.ktt-btn:disabled { opacity:.45; cursor:not-allowed; }
.ktt-btn-primary  { background:#1C2B4A; color:#fff; }
.ktt-btn-success  { background:#2ECC71; color:#fff; }
.ktt-btn-danger   { background:#E74C3C; color:#fff; }
.ktt-btn-reset    { background:#ECF0F1; color:#555; border:1px solid #D5D8DC; }
.ktt-btn-group    { display:flex; gap:10px; flex-wrap:wrap; margin:14px 0; }

/* ── Badge ── */
.ktt-badge      { display:inline-block; padding:4px 14px; border-radius:20px; font-size:13px; font-weight:600; }
.ktt-badge-pass { background:#D5F5E3; color:#1E8449; }
.ktt-badge-fail { background:#FADBD8; color:#922B21; }
.ktt-badge-warn { background:#FEF9E7; color:#9A7D0A; }
.ktt-badge-info { background:#D6EAF8; color:#1A5276; }

/* ── Log ── */
.ktt-log {
    background:#fff; border:1px solid #DDE2EE; border-radius:8px;
    padding:10px 14px; max-height:180px; overflow-y:auto;
    font-family:monospace; font-size:12.5px; line-height:1.7; color:#333; margin:10px 0;
}
.ktt-log-chatter { color:#E74C3C; font-weight:700; }
.ktt-log-ok      { color:#27AE60; }

/* ── Big number (CPS / spacebar) ── */
.ktt-big-number { font-size:64px; font-weight:800; text-align:center; color:#1a1a2e; line-height:1; margin:14px 0 4px; }
.ktt-big-label  { text-align:center; font-size:12px; color:#7F8C9A; letter-spacing:.07em; text-transform:uppercase; margin-bottom:14px; }

/* ── Hz display ── */
.ktt-hz-display { font-size:52px; font-weight:800; color:#3B8BEB; text-align:center; margin:12px 0 2px; }

/* ── Held chips (rollover) ── */
.ktt-held-list { display:flex; flex-wrap:wrap; gap:6px; margin:10px 0; min-height:38px; }
.ktt-held-chip { background:#3B8BEB; color:#fff; border-radius:6px; padding:5px 13px; font-size:13px; font-weight:600; }

.ktt-note { font-size:12px; color:#9aa1ae; margin-top:8px; line-height:1.6; }

/* ── Responsive ── */
@media (max-width:600px) {
    .ktt-wrap       { padding:16px 10px; }
    .kb-key .kb-sub,
    .kb-key .kb-alt { display:none; }
    .ktt-big-number { font-size:48px; }
    .ktt-stat span  { font-size:18px; }
    .ktt-stat-row   { gap:18px; }
}
