:root {
    --brand: #4f46e5;
    --brand-dark: #4338ca;
    --brand-soft: #eef2ff;
    --ink: #111827;
    --ink-muted: #6b7280;
    --surface: #ffffff;
    --canvas: #f7f7fb;
    --line: #e5e7eb;
    --radius: 14px;
}

html, body {
    font-family: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
    background-color: var(--canvas);
    color: var(--ink);
}

a {
    color: var(--brand);
    text-decoration: none;
}

a:hover {
    color: var(--brand-dark);
    text-decoration: underline;
}

h1:focus {
    outline: none;
}

.fbc-icon {
    flex: 0 0 auto;
}

/* ---------- Buttons ---------- */

.btn-primary {
    --bs-btn-bg: var(--brand);
    --bs-btn-border-color: var(--brand);
    --bs-btn-hover-bg: var(--brand-dark);
    --bs-btn-hover-border-color: var(--brand-dark);
    --bs-btn-active-bg: var(--brand-dark);
    --bs-btn-active-border-color: var(--brand-dark);
    --bs-btn-disabled-bg: var(--brand);
    --bs-btn-disabled-border-color: var(--brand);
}

.btn-outline-primary {
    --bs-btn-color: var(--brand);
    --bs-btn-border-color: var(--brand);
    --bs-btn-hover-bg: var(--brand);
    --bs-btn-hover-border-color: var(--brand);
    --bs-btn-active-bg: var(--brand-dark);
    --bs-btn-active-border-color: var(--brand-dark);
}

.form-control:focus, .form-select:focus {
    border-color: var(--brand);
    box-shadow: 0 0 0 0.2rem rgba(79, 70, 229, 0.15);
}

/* ---------- Shell ---------- */

.app-shell {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
}

.app-main {
    flex: 1 0 auto;
}

.app-navbar {
    background: linear-gradient(120deg, #1e1b4b 0%, #312e81 55%, #4338ca 100%);
    box-shadow: 0 1px 0 rgba(255, 255, 255, 0.06), 0 6px 24px rgba(17, 24, 39, 0.12);
}

.app-navbar .navbar-brand,
.app-navbar .nav-link {
    color: rgba(255, 255, 255, 0.9);
}

/* Last resort if the group list ever outgrows the row again: wrap rather than overflow. */
.app-navbar .navbar-nav {
    flex-wrap: wrap;
}

.app-navbar .navbar-brand {
    font-weight: 650;
    letter-spacing: -0.01em;
}

.app-navbar .nav-link:hover,
.app-navbar .nav-link:focus,
.app-navbar .navbar-brand:hover {
    color: #fff;
    text-decoration: none;
}

.app-navbar .nav-link.active {
    color: #fff;
    font-weight: 600;
}

.app-navbar .navbar-toggler {
    border-color: rgba(255, 255, 255, 0.35);
}

.app-navbar .navbar-toggler-icon {
    filter: invert(1) grayscale(1) brightness(2);
}

.app-footer {
    border-top: 1px solid var(--line);
    background: var(--surface);
    padding: 1.25rem 0;
    margin-top: 3rem;
}

/* ---------- Page furniture ---------- */

.hero {
    background: linear-gradient(180deg, #ffffff 0%, var(--canvas) 100%);
    border-bottom: 1px solid var(--line);
    padding: 3.25rem 0 2.5rem;
}

.hero-title {
    font-size: clamp(2rem, 4vw, 2.75rem);
    font-weight: 700;
    letter-spacing: -0.02em;
    margin-bottom: 0.5rem;
}

.hero-subtitle {
    color: var(--ink-muted);
    font-size: 1.075rem;
    max-width: 46rem;
    margin-bottom: 0;
}

.page-body {
    padding-top: 2rem;
}

.page-header {
    margin-bottom: 1.75rem;
}

.page-title {
    font-size: clamp(1.6rem, 3vw, 2.1rem);
    font-weight: 700;
    letter-spacing: -0.02em;
    margin-bottom: 0.35rem;
}

.page-subtitle {
    color: var(--ink-muted);
    max-width: 46rem;
    margin-bottom: 0;
}

.breadcrumb {
    --bs-breadcrumb-divider: '/';
}

/* ---------- Tool catalog ---------- */

.tool-group + .tool-group {
    margin-top: 2.5rem;
}

.tool-group-header {
    display: flex;
    align-items: flex-start;
    gap: 0.85rem;
    margin-bottom: 1rem;
}

.tool-group-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.5rem;
    height: 2.5rem;
    border-radius: 12px;
    background: var(--brand-soft);
    color: var(--brand);
}

.tool-group-title {
    font-size: 1.25rem;
    font-weight: 650;
    margin-bottom: 0.15rem;
}

.tool-group-desc {
    color: var(--ink-muted);
    font-size: 0.95rem;
    margin-bottom: 0;
}

.tool-card-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
    gap: 1rem;
}

.tool-card {
    display: flex;
    align-items: center;
    gap: 0.9rem;
    padding: 1.05rem 1.1rem;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    color: inherit;
    transition: border-color .15s ease, box-shadow .15s ease, transform .15s ease;
}

.tool-card:hover {
    border-color: var(--brand);
    box-shadow: 0 8px 24px rgba(79, 70, 229, 0.12);
    transform: translateY(-1px);
    text-decoration: none;
    color: inherit;
}

.tool-card-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.6rem;
    height: 2.6rem;
    flex: 0 0 auto;
    border-radius: 12px;
    background: var(--brand-soft);
    color: var(--brand);
}

.tool-card-body {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    min-width: 0;
}

.tool-card-title {
    font-weight: 600;
}

.tool-card-desc {
    color: var(--ink-muted);
    font-size: 0.875rem;
}

.tool-card-go {
    margin-left: auto;
    color: var(--ink-muted);
}

.tool-card:hover .tool-card-go {
    color: var(--brand);
}

/* ---------- Tool page ---------- */

.tool-app {
    max-width: 56rem;
}

.tool-panel {
    border: 1px solid var(--line);
    border-radius: var(--radius);
    box-shadow: 0 1px 2px rgba(17, 24, 39, 0.04);
}

.tool-panel .card-body {
    padding: 1.35rem;
}

.tool-output {
    margin-top: 2rem;
}

.tool-notes {
    margin-top: 2.5rem;
    padding: 1.1rem 1.25rem;
    background: var(--brand-soft);
    border-radius: var(--radius);
}

.tool-notes ul {
    margin-bottom: 0;
    padding-left: 1.1rem;
    color: #3f3f6b;
    font-size: 0.9rem;
}

.tool-notes li + li {
    margin-top: 0.35rem;
}

/* ---------- Direct link generator results ---------- */

.dlg-results {
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

.dlg-item {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: 0.85rem 1rem 0.9rem;
}

.dlg-item-invalid {
    border-color: #f1b0b7;
    background: #fff7f7;
}

.dlg-item-label {
    display: block;
    font-weight: 600;
    font-size: 0.875rem;
    margin-bottom: 0.4rem;
}

.dlg-link-input {
    background: #fbfbfe;
}

.dlg-item-source {
    margin-top: 0.4rem;
    font-size: 0.78rem;
    color: var(--ink-muted);
    overflow-wrap: anywhere;
}

.dlg-item-warning {
    margin-top: 0.45rem;
    font-size: 0.82rem;
    color: #92400e;
}

.dlg-item-error {
    margin-top: 0.45rem;
    font-size: 0.85rem;
    color: #b02a37;
}

/* ---------- Draw and pick ---------- */

.raf-heading {
    margin-top: 1.1rem;
    margin-bottom: 0.5rem;
    color: var(--ink-muted);
}

.raf-list {
    list-style: none;
    counter-reset: raf;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.raf-list li {
    counter-increment: raf;
    display: flex;
    align-items: baseline;
    gap: 0.75rem;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: 0.6rem 0.9rem;
    /* A pasted entry can be one unbroken string; without this it widens the whole page. */
    overflow-wrap: anywhere;
}

.raf-list li::before {
    content: counter(raf);
    flex: 0 0 auto;
    min-width: 1.75rem;
    font-weight: 600;
    /* Tabular figures so 9 and 10 do not shift the names beside them. */
    font-variant-numeric: tabular-nums;
    color: var(--brand);
}

.raf-note {
    font-size: 0.85rem;
    color: #92400e;
}

.raf-seed-out {
    margin-top: 1.1rem;
    margin-bottom: 0;
    font-size: 0.85rem;
    color: var(--ink-muted);
    overflow-wrap: anywhere;
}

.whl-stage {
    position: relative;
    width: 100%;
    max-width: 420px;
}

.whl-canvas {
    display: block;
    width: 100%;
    /* The drawing is square; the backing store is sized from clientWidth in the module. */
    aspect-ratio: 1;
}

/* Outside the canvas on purpose: the wheel turns and the pointer must not. */
.whl-pointer {
    position: absolute;
    top: -3px;
    left: 50%;
    transform: translateX(-50%);
    width: 0;
    height: 0;
    border-left: 11px solid transparent;
    border-right: 11px solid transparent;
    border-top: 20px solid var(--ink);
    z-index: 1;
}

.whl-result {
    margin-top: 1rem;
    text-align: center;
}

.whl-result-label {
    font-size: 0.82rem;
    color: var(--ink-muted);
}

.whl-winner {
    font-size: 1.45rem;
    font-weight: 700;
    line-height: 1.25;
    overflow-wrap: anywhere;
}

.whl-result-seed {
    margin-top: 0.35rem;
    font-size: 0.8rem;
    color: var(--ink-muted);
    overflow-wrap: anywhere;
}

.brk-rounds {
    display: flex;
    flex-direction: column;
    gap: 1.35rem;
}

.brk-round-name {
    margin-bottom: 0.5rem;
    color: var(--ink-muted);
}

.brk-matches {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.45rem;
}

.brk-matches li {
    display: flex;
    align-items: baseline;
    gap: 0.75rem;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: 0.55rem 0.9rem;
}

.brk-no {
    flex: 0 0 auto;
    min-width: 2.75rem;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    color: var(--brand);
}

.brk-pair {
    overflow-wrap: anywhere;
}

.brk-bye .brk-pair {
    color: var(--ink-muted);
}

.grp-board {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
    gap: 0.9rem;
}

.grp-card {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: 0.75rem 0.9rem 0.85rem;
}

.grp-name {
    margin-bottom: 0.5rem;
    color: var(--brand);
}

.grp-members {
    margin: 0;
    padding-left: 1.25rem;
}

.grp-members li {
    overflow-wrap: anywhere;
}

.sst-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.45rem;
}

.sst-list li {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: 0.55rem 0.9rem;
    overflow-wrap: anywhere;
}

.dic-result {
    text-align: center;
    padding: 0.5rem 0 0.25rem;
}

.dic-headline {
    font-size: 2.6rem;
    font-weight: 700;
    line-height: 1.1;
    color: var(--brand);
}

.dic-detail {
    margin-top: 0.4rem;
    font-size: 0.85rem;
    color: var(--ink-muted);
    overflow-wrap: anywhere;
}

.bgo-caller {
    margin-bottom: 1rem;
}

.bgo-current-label {
    font-size: 0.8rem;
    color: var(--ink-muted);
}

.bgo-current {
    font-size: 2.2rem;
    font-weight: 700;
    line-height: 1.1;
    color: var(--brand);
    font-variant-numeric: tabular-nums;
}

.bgo-called {
    display: flex;
    flex-wrap: wrap;
    gap: 0.3rem;
    margin-top: 0.85rem;
}

.bgo-chip {
    min-width: 2rem;
    text-align: center;
    padding: 0.15rem 0.4rem;
    border: 1px solid var(--line);
    border-radius: 999px;
    font-size: 0.8rem;
    font-variant-numeric: tabular-nums;
    background: var(--surface);
}

.bgo-cards {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    gap: 0.9rem;
}

.bgo-card {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: 0.7rem 0.8rem 0.8rem;
}

.bgo-card-name {
    margin-bottom: 0.5rem;
    color: var(--ink-muted);
}

.bgo-grid {
    width: 100%;
    border-collapse: collapse;
    font-variant-numeric: tabular-nums;
}

.bgo-grid td {
    border: 1px solid var(--line);
    text-align: center;
    padding: 0.35rem 0.1rem;
    font-weight: 600;
    /* Nine equal columns whatever the numbers are, so the cards line up when printed. */
    width: 11.11%;
}

.bgo-empty {
    background: var(--canvas);
}

/* ---------- Shared tool controls ---------- */

.tool-drop {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.35rem;
    width: 100%;
    padding: 2rem 1rem;
    border: 2px dashed var(--line);
    border-radius: var(--radius);
    background: #fbfbfe;
    color: var(--brand);
    cursor: pointer;
    text-align: center;
    transition: border-color .15s ease, background-color .15s ease;
}

.tool-drop:hover,
.tool-drop.is-over,
.tool-file-input:focus-visible + .tool-drop {
    border-color: var(--brand);
    background: var(--brand-soft);
}

.tool-drop-title {
    font-weight: 600;
    color: var(--ink);
}

.tool-drop-hint {
    font-size: 0.85rem;
    color: var(--ink-muted);
}

/* Sits behind every decoded image — PNG, WebP, AVIF and SVG are routinely transparent,
   and a plain white panel would hide exactly the part the visitor wants to check. */
.b64-checker {
    background-color: #fff;
    background-image:
        linear-gradient(45deg, #eceff4 25%, transparent 25%),
        linear-gradient(-45deg, #eceff4 25%, transparent 25%),
        linear-gradient(45deg, transparent 75%, #eceff4 75%),
        linear-gradient(-45deg, transparent 75%, #eceff4 75%);
    background-size: 12px 12px;
    background-position: 0 0, 0 6px, 6px -6px, -6px 0;
}

.b64-results {
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

.b64-item {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: 0.85rem 1rem 0.9rem;
}

.b64-item-invalid {
    border-color: #f1b0b7;
    background: #fff7f7;
}

.b64-item-head {
    display: flex;
    align-items: center;
    gap: 0.85rem;
    margin-bottom: 0.65rem;
}

.b64-thumb {
    width: 3.5rem;
    height: 3.5rem;
    flex: 0 0 auto;
    object-fit: contain;
    border: 1px solid var(--line);
    border-radius: 10px;
}

.b64-item-info {
    min-width: 0;
    flex: 1 1 auto;
}

.b64-item-name {
    font-weight: 600;
    overflow-wrap: anywhere;
}

.b64-item-meta {
    font-size: 0.8rem;
    color: var(--ink-muted);
    overflow-wrap: anywhere;
}

.b64-item-actions {
    display: flex;
    gap: 0.4rem;
    margin-left: auto;
    flex: 0 0 auto;
}

.b64-output-label {
    display: block;
    font-size: 0.8rem;
    font-weight: 600;
    color: var(--ink-muted);
    margin-bottom: 0.25rem;
}

.b64-output {
    font-size: 0.78rem;
    background: #fbfbfe;
    resize: vertical;
}

.b64-item-error {
    font-size: 0.85rem;
    color: #b02a37;
}

.tool-warning {
    margin-bottom: 0.5rem;
    font-size: 0.85rem;
    color: #92400e;
}

/* ---------- Base64 tools ---------- */

.b64-result-card {
    display: flex;
    flex-direction: column;
    gap: 1rem;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: 1.1rem 1.25rem 1.25rem;
}

.b64-preview {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1rem;
    border: 1px solid var(--line);
    border-radius: 12px;
}

.b64-preview-image {
    max-width: 100%;
    max-height: 26rem;
    object-fit: contain;
}

.b64-meta {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
    gap: 0.75rem;
    margin-bottom: 0;
}

.b64-meta-item dt {
    font-size: 0.78rem;
    font-weight: 600;
    color: var(--ink-muted);
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.b64-meta-item dd {
    margin-bottom: 0;
    overflow-wrap: anywhere;
}

/* ---------- Case converter ---------- */

.case-results {
    display: flex;
    flex-direction: column;
    gap: 0.85rem;
}

.case-item-label {
    display: block;
    font-size: 0.8rem;
    font-weight: 600;
    color: var(--ink-muted);
    margin-bottom: 0.25rem;
}

.case-output {
    background: #fbfbfe;
    resize: vertical;
    /* Results are prose, not code — a monospace box would misrepresent what they are. */
    overflow-wrap: anywhere;
}

/* ---------- Line tools ---------- */

.line-options {
    border: 0;
    padding: 0;
    margin: 0;
}

.line-options legend {
    float: none;   /* Bootstrap makes legend full-width and 1.5rem; this is a normal label. */
    width: auto;
    font-size: 1rem;
}

.line-option-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
    gap: 0.35rem 1rem;
}

.line-result {
    font-size: 0.82rem;
    background: #fbfbfe;
    resize: vertical;
}

/* ---------- Hash tools ---------- */

.hash-results {
    display: flex;
    flex-direction: column;
    gap: 0.85rem;
}

.hash-item-label {
    display: block;
    font-size: 0.8rem;
    font-weight: 600;
    color: var(--ink-muted);
    margin-bottom: 0.25rem;
}

.hash-output {
    font-size: 0.8rem;
    background: #fbfbfe;
    resize: vertical;
    /* A SHA-512 in hex is 128 characters; wrapping beats a box nobody can read across. */
    overflow-wrap: anywhere;
}

.sum-verdict {
    padding: 0.6rem 0.85rem;
    border-radius: 10px;
    font-size: 0.9rem;
    font-weight: 600;
    margin-bottom: 1rem;
}

.sum-verdict-match {
    background: #dcfce7;
    color: #14532d;
}

.sum-verdict-mismatch {
    background: #fee2e2;
    color: #7f1d1d;
}

/* ---------- Counter ---------- */

.tool-app-wide {
    max-width: 72rem;
}

.count-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
    gap: 0.85rem;
    margin-bottom: 0;
}

.count-item {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: 12px;
    padding: 0.7rem 0.9rem;
}

.count-item dt {
    font-size: 0.75rem;
    font-weight: 600;
    color: var(--ink-muted);
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.count-item dd {
    margin-bottom: 0;
    font-size: 1.35rem;
    font-weight: 650;
    letter-spacing: -0.01em;
}

.count-frequency {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
    list-style: none;
    padding-left: 0;
    margin-bottom: 0;
}

.count-frequency-item {
    display: inline-flex;
    align-items: baseline;
    gap: 0.4rem;
    padding: 0.3rem 0.6rem;
    border-radius: 999px;
    background: var(--brand-soft);
    font-size: 0.85rem;
}

.count-frequency-word {
    font-weight: 600;
    overflow-wrap: anywhere;
}

.count-frequency-count {
    color: var(--ink-muted);
    font-size: 0.78rem;
}

/* ---------- Diff ---------- */

.diff-rows {
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--surface);
    overflow-x: auto;
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 0.82rem;
}

.diff-row {
    display: flex;
    gap: 0.65rem;
    padding: 0.15rem 0.75rem;
    white-space: pre-wrap;
    overflow-wrap: anywhere;
}

.diff-row-numbers {
    flex: 0 0 4.5rem;
    color: var(--ink-muted);
    text-align: right;
    user-select: none;
}

.diff-row-marker {
    flex: 0 0 1ch;
    font-weight: 700;
    user-select: none;
}

.diff-row-text {
    flex: 1 1 auto;
}

.diff-row-added {
    background: #e7f8ee;
    color: #14532d;
}

.diff-row-removed {
    background: #fdecec;
    color: #7f1d1d;
}

/* ---------- Toasts ---------- */

.toast-stack {
    position: fixed;
    right: 1rem;
    bottom: 1rem;
    z-index: 1080;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    pointer-events: none;
}

.fbc-toast {
    min-width: 12rem;
    max-width: 22rem;
    padding: 0.6rem 0.9rem;
    border-radius: 10px;
    color: #fff;
    font-size: 0.9rem;
    box-shadow: 0 10px 30px rgba(17, 24, 39, 0.22);
    animation: fbc-toast-in .18s ease-out;
}

.fbc-toast-leaving {
    opacity: 0;
    transform: translateY(6px);
    transition: opacity .25s ease, transform .25s ease;
}

.fbc-toast-success { background: #16794c; }
.fbc-toast-danger { background: #b02a37; }
.fbc-toast-warning { background: #9a6700; }
.fbc-toast-info { background: #1f6feb; }

@keyframes fbc-toast-in {
    from { opacity: 0; transform: translateY(8px); }
    to { opacity: 1; transform: translateY(0); }
}

/* ---------- Blazor error UI ---------- */

#blazor-error-ui {
    color-scheme: light only;
    background: lightyellow;
    bottom: 0;
    box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
    box-sizing: border-box;
    display: none;
    left: 0;
    padding: 0.6rem 1.25rem 0.7rem 1.25rem;
    position: fixed;
    width: 100%;
    z-index: 1090;
}

#blazor-error-ui .dismiss {
    cursor: pointer;
    position: absolute;
    right: 0.75rem;
    top: 0.5rem;
}

/* ---------- Data group ---------- */

.csv-table-wrap {
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--surface);
    /* Wide sheets scroll inside the box rather than pushing the page sideways. */
    overflow-x: auto;
    max-height: 34rem;
    overflow-y: auto;
}

.csv-table {
    font-size: 0.85rem;
    margin-bottom: 0;
    white-space: nowrap;
}

.csv-table thead th {
    position: sticky;
    top: 0;
    background: var(--brand-soft);
    z-index: 1;
}

.jd-rows {
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--surface);
    overflow-x: auto;
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 0.82rem;
}

.jd-row {
    display: flex;
    gap: 0.65rem;
    padding: 0.25rem 0.75rem;
    align-items: baseline;
}

.jd-row + .jd-row {
    border-top: 1px solid var(--line);
}

.jd-row-marker {
    flex: 0 0 1ch;
    font-weight: 700;
}

.jd-row-path {
    flex: 0 0 auto;
    font-weight: 600;
    overflow-wrap: anywhere;
}

.jd-row-value {
    flex: 1 1 auto;
    color: var(--ink-muted);
    overflow-wrap: anywhere;
}

.jd-row-added { background: #e7f8ee; }
.jd-row-removed { background: #fdecec; }
.jd-row-changed { background: #fff7e6; }

/* ---------- Time and numbers ---------- */

.calc-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
    gap: 0.85rem;
    margin-bottom: 0;
}

.calc-item {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: 12px;
    padding: 0.7rem 0.9rem;
}

.calc-item dt {
    font-size: 0.75rem;
    font-weight: 600;
    color: var(--ink-muted);
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.calc-item dd {
    margin-bottom: 0;
    font-size: 1rem;
    overflow-wrap: anywhere;
}

.tz-rows, .cron-fields {
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--surface);
    overflow-x: auto;
}

.tz-row, .cron-field {
    display: flex;
    gap: 0.85rem;
    align-items: baseline;
    padding: 0.5rem 0.9rem;
}

.tz-row + .tz-row, .cron-field + .cron-field {
    border-top: 1px solid var(--line);
}

.tz-row-zone, .cron-field-name {
    flex: 0 0 13rem;
    font-weight: 600;
    overflow-wrap: anywhere;
}

.tz-row-when {
    flex: 1 1 auto;
}

.tz-row-offset {
    flex: 0 0 auto;
    color: var(--ink-muted);
    font-variant-numeric: tabular-nums;
}

.cron-field-raw {
    flex: 0 0 5rem;
    color: var(--brand-dark);
}

.cron-field-values {
    flex: 1 1 auto;
    color: var(--ink-muted);
    overflow-wrap: anywhere;
}

.cron-runs {
    margin-bottom: 0;
    padding-left: 1.25rem;
}

.cron-runs li + li {
    margin-top: 0.25rem;
}

.base-results {
    display: flex;
    flex-direction: column;
    gap: 0.85rem;
}

.base-item-label {
    display: block;
    font-size: 0.8rem;
    font-weight: 600;
    color: var(--ink-muted);
    margin-bottom: 0.25rem;
}

.roman-result {
    font-size: 1.25rem;
    letter-spacing: 0.05em;
}

.bytes-list {
    border: 1px solid var(--line);
    border-radius: 12px;
    background: var(--surface);
}

.bytes-row {
    display: flex;
    justify-content: space-between;
    gap: 1rem;
    padding: 0.4rem 0.85rem;
}

.bytes-row + .bytes-row {
    border-top: 1px solid var(--line);
}

.bytes-row-unit {
    font-weight: 600;
}

.bytes-row-value {
    font-variant-numeric: tabular-nums;
    overflow-wrap: anywhere;
}

/* ---------- Colour ---------- */

.cc-layout {
    display: flex;
    flex-wrap: wrap;
    gap: 1.25rem;
    align-items: flex-start;
}

.cc-swatch {
    flex: 0 0 auto;
    width: 9rem;
    height: 9rem;
    border-radius: var(--radius);
    border: 1px solid var(--line);
    /* Checkerboard behind it so a translucent colour reads as translucent. */
    background-color: #fff;
    background-image:
        linear-gradient(45deg, #eceff4 25%, transparent 25%),
        linear-gradient(-45deg, #eceff4 25%, transparent 25%),
        linear-gradient(45deg, transparent 75%, #eceff4 75%),
        linear-gradient(-45deg, transparent 75%, #eceff4 75%);
    background-size: 12px 12px;
    background-position: 0 0, 0 6px, 6px -6px, -6px 0;
}

.cc-formats {
    flex: 1 1 20rem;
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

.cc-format-label {
    display: block;
    font-size: 0.78rem;
    font-weight: 600;
    color: var(--ink-muted);
    letter-spacing: 0.04em;
    margin-bottom: 0.2rem;
}

.ct-preview {
    padding: 1.5rem;
    border-radius: var(--radius);
    border: 1px solid var(--line);
}

.ct-preview-normal {
    font-size: 1rem;
}

.ct-preview-large {
    font-size: 1.5rem;
    font-weight: 700;
}

.ct-pass {
    color: #14532d;
    font-weight: 650;
}

.ct-fail {
    color: #7f1d1d;
    font-weight: 650;
}

.sh-scale {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(7rem, 1fr));
    gap: 0.5rem;
}

.sh-swatch {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    align-items: flex-start;
    padding: 1rem 0.75rem;
    border: 1px solid var(--line);
    border-radius: 12px;
    cursor: pointer;
    text-align: left;
}

.sh-swatch-step {
    font-size: 0.7rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    opacity: 0.75;
}

.sh-swatch-value {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 0.8rem;
}

.gr-preview {
    height: 12rem;
    border-radius: var(--radius);
    border: 1px solid var(--line);
}

/* ---------- Web development ---------- */

.rx-highlight {
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--surface);
    padding: 0.85rem 1rem;
    max-height: 22rem;
    overflow: auto;
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 0.82rem;
    line-height: 1.6;
    /* The subject is shown verbatim: its own line breaks and runs of spaces are part of
       what the pattern matched against. */
    white-space: pre-wrap;
    overflow-wrap: anywhere;
}

.rx-mark {
    background: #fde68a;
    color: inherit;
    padding: 0.05rem 0;
    border-radius: 3px;
}

.rx-mark-alt {
    background: #bfdbfe;
}

.rx-mark-empty {
    /* Nothing to paint, so the match is drawn as a caret between two characters. */
    border-left: 2px solid #b45309;
    margin-left: -1px;
}

.rx-rows {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    max-height: 24rem;
    overflow-y: auto;
}

.rx-row {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.5rem 0.75rem;
    padding: 0.55rem 0.8rem;
    border: 1px solid var(--line);
    border-radius: 12px;
    background: var(--surface);
}

.rx-row-index {
    font-size: 0.72rem;
    font-weight: 600;
    color: var(--ink-muted);
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.rx-row-value {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 0.85rem;
    overflow-wrap: anywhere;
}

.rx-groups {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem;
    list-style: none;
    padding-left: 0;
    margin: 0;
    flex-basis: 100%;
}

.rx-group {
    display: inline-flex;
    align-items: baseline;
    gap: 0.4rem;
    padding: 0.2rem 0.55rem;
    border-radius: 999px;
    background: var(--brand-soft);
    font-size: 0.8rem;
}

.rx-group-name {
    font-weight: 600;
    color: #4338ca;
}

.rx-group-value {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    overflow-wrap: anywhere;
}

.jwt-verdict {
    padding: 0.6rem 0.85rem;
    border-radius: 10px;
    font-size: 0.9rem;
    font-weight: 600;
}

.jwt-verdict-valid {
    background: #dcfce7;
    color: #14532d;
}

.jwt-verdict-invalid {
    background: #fee2e2;
    color: #7f1d1d;
}

.jwt-verdict-neutral {
    background: var(--brand-soft);
    color: #3f3f6b;
}

.jwt-json {
    font-size: 0.8rem;
    background: #fbfbfe;
    resize: vertical;
}

.jwt-ok { color: #14532d; font-weight: 650; }
.jwt-bad { color: #7f1d1d; font-weight: 650; }
.jwt-warn { color: #92400e; font-weight: 650; }

.hs-section + .hs-section {
    margin-top: 2rem;
}

.hs-section-title {
    margin-bottom: 0.6rem;
    color: var(--ink-muted);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    font-size: 0.75rem;
}

.hs-rows {
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--surface);
    overflow: hidden;
}

.hs-row {
    display: flex;
    align-items: baseline;
    gap: 0.9rem;
    padding: 0.6rem 0.9rem;
}

.hs-row + .hs-row {
    border-top: 1px solid var(--line);
}

.hs-code {
    flex: 0 0 3rem;
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-weight: 700;
    font-size: 0.95rem;
}

.hs-body {
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
}

.hs-reason {
    font-weight: 600;
    font-size: 0.9rem;
}

.hs-meaning {
    font-size: 0.85rem;
    color: var(--ink-muted);
}

.mime-rows {
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--surface);
    overflow: hidden;
}

.mime-row {
    display: grid;
    grid-template-columns: minmax(8rem, 1fr) minmax(12rem, 2fr) minmax(5rem, 0.7fr);
    align-items: center;
    gap: 0.75rem;
    padding: 0.55rem 0.9rem;
}

.mime-row + .mime-row {
    border-top: 1px solid var(--line);
}

.mime-row-head {
    background: var(--brand-soft);
    font-size: 0.72rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: #3f3f6b;
}

.mime-extensions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.3rem;
}

.mime-extensions code {
    font-size: 0.8rem;
    color: var(--ink);
}

.mime-type {
    /* A plain button so the whole type can be copied with one click, styled as the text
       it is rather than as a control. */
    border: 0;
    background: none;
    padding: 0;
    text-align: left;
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 0.82rem;
    color: var(--brand);
    overflow-wrap: anywhere;
}

.mime-type:hover {
    text-decoration: underline;
}

.mime-row-head .mime-type {
    color: inherit;
    font-family: inherit;
    font-size: inherit;
}

.mime-category {
    font-size: 0.8rem;
    color: var(--ink-muted);
}

.ua-notes, .mg-warnings, .env-problems {
    margin-bottom: 0;
    padding: 0.75rem 1rem 0.75rem 2rem;
    border-radius: var(--radius);
    background: #fffbeb;
    color: #92400e;
    font-size: 0.85rem;
}

.ua-notes li + li, .mg-warnings li + li, .env-problems li + li {
    margin-top: 0.3rem;
}

.env-problems {
    margin-bottom: 1rem;
}

.mg-card {
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--surface);
    overflow: hidden;
}

.mg-card-image {
    display: block;
    width: 100%;
    /* What every platform crops a large card to. */
    aspect-ratio: 1.91 / 1;
    object-fit: cover;
    background: var(--canvas);
}

.mg-card-body {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    padding: 0.8rem 1rem 0.9rem;
}

.mg-card-host {
    font-size: 0.7rem;
    letter-spacing: 0.05em;
    color: var(--ink-muted);
}

.mg-card-title {
    font-weight: 650;
    line-height: 1.3;
}

.mg-card-description {
    font-size: 0.85rem;
    color: var(--ink-muted);
}

.mg-result {
    font-size: 0.78rem;
    background: #fbfbfe;
    resize: vertical;
}

@media (max-width: 575.98px) {
    .mime-row {
        grid-template-columns: 1fr;
        gap: 0.2rem;
    }

    .hs-row {
        flex-direction: column;
        gap: 0.2rem;
    }
}

/* ---------- Navigation menu panel ---------- */

.tool-group {
    /* The navbar is sticky, so an anchor jump would land under it. */
    scroll-margin-top: 5rem;
}

.nav-mega {
    padding: 1rem;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    box-shadow: 0 12px 32px rgba(17, 24, 39, 0.12);
    /* Never taller than the screen it drops into. */
    max-height: min(32rem, calc(100vh - 5rem));
    overflow-y: auto;
}

.nav-mega-grid {
    display: grid;
    /* The panel's width comes from the columns, not from the number of groups, which is
       what stops the menu growing every time the catalogue does. */
    grid-template-columns: repeat(3, minmax(11rem, 1fr));
    gap: 1rem 1.75rem;
}

.nav-mega-title {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    margin-bottom: 0.35rem;
    color: var(--ink);
    font-size: 0.78rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.nav-mega-title:hover {
    color: var(--brand);
    text-decoration: none;
}

.nav-mega-list {
    list-style: none;
    padding-left: 0;
    margin-bottom: 0;
}

.nav-mega-link {
    display: block;
    padding: 0.2rem 0.35rem;
    border-radius: 8px;
    color: var(--ink-muted);
    font-size: 0.85rem;
}

.nav-mega-link:hover, .nav-mega-link:focus {
    background: var(--brand-soft);
    color: var(--brand-dark);
    text-decoration: none;
}

.nav-mega-all {
    display: block;
    margin-top: 0.9rem;
    padding-top: 0.75rem;
    border-top: 1px solid var(--line);
    font-size: 0.85rem;
    font-weight: 600;
}

@media (max-width: 991.98px) {
    .nav-mega {
        border: 0;
        box-shadow: none;
        padding: 0.5rem 0 0;
        max-height: none;
    }

    .nav-mega-grid {
        grid-template-columns: 1fr;
        gap: 0.9rem;
    }
}

/* ---------- Türkiye ---------- */

.tr-privacy {
    display: flex;
    align-items: flex-start;
    gap: 0.6rem;
    margin-bottom: 1.25rem;
    padding: 0.75rem 1rem;
    border-radius: var(--radius);
    background: var(--brand-soft);
    color: #3f3f6b;
    font-size: 0.85rem;
}

.tr-number {
    /* These are numbers people read back digit by digit, so give them room. */
    font-size: 1.05rem;
    letter-spacing: 0.06em;
}

.tr-ok { color: #14532d; font-weight: 650; }
.tr-bad { color: #7f1d1d; font-weight: 650; }

.plate-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr));
    gap: 0.5rem;
}

.plate-item {
    display: flex;
    align-items: baseline;
    gap: 0.6rem;
    padding: 0.5rem 0.8rem;
    border: 1px solid var(--line);
    border-radius: 12px;
    background: var(--surface);
}

.plate-code {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-weight: 700;
    font-size: 0.95rem;
    color: var(--brand);
}

.plate-name {
    font-size: 0.9rem;
    overflow-wrap: anywhere;
}

/* ---------- Base64 file tools ---------- */

.b2f-hex {
    margin-bottom: 0;
    padding: 0.75rem 1rem;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--surface);
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 0.82rem;
    /* A hex dump is a fixed-width grid; wrapping it would destroy the only thing it is for. */
    overflow-x: auto;
    white-space: pre;
}

/* ---------- QR code ---------- */

.qr-preview {
    display: flex;
    justify-content: center;
    padding: 1rem;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--surface);
}

.qr-preview svg {
    width: 100%;
    /* Large enough to scan off a screen, small enough not to fill the page on a phone. */
    max-width: 18rem;
    height: auto;
}

/* ---------- Lists ---------- */

.list-buckets {
    display: grid;
    /* Three across on a wide screen, stacked on a phone: a 12rem box is unreadable, and the
       three buckets are only worth seeing side by side when they can be read side by side. */
    grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr));
    gap: 1rem;
}

.list-bucket {
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--surface);
    padding: 0.85rem;
}

.list-bucket-head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
    margin-bottom: 0.6rem;
}

.list-bucket-title {
    font-size: 0.95rem;
    font-weight: 650;
    margin-bottom: 0;
    margin-right: auto;
}

.list-bucket-count {
    font-size: 0.78rem;
    color: var(--ink-muted);
    white-space: nowrap;
}

.dup-rows {
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--surface);
    list-style: none;
    padding-left: 0;
    margin-bottom: 0;
    overflow: hidden;
}

.dup-row {
    display: flex;
    align-items: baseline;
    gap: 0.75rem;
    padding: 0.5rem 0.9rem;
}

.dup-row + .dup-row {
    border-top: 1px solid var(--line);
}

.dup-row-line {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 0.85rem;
    margin-right: auto;
    /* A pasted list can hold a line with no spaces in it that is longer than the box. */
    overflow-wrap: anywhere;
}

.dup-row-count {
    font-size: 0.78rem;
    color: var(--ink-muted);
    white-space: nowrap;
}

/* ---------- Image tools ---------- */

/* A control the current mode does not read stays visible but stops asking to be filled in. */
.is-inactive {
    opacity: 0.45;
}

.ic-after {
    font-weight: 600;
}

.ic-smaller {
    color: #14532d;
}

.ic-larger {
    color: #92400e;
}

.cr-stage {
    position: relative;
    display: inline-block;
    max-width: 100%;
    line-height: 0;
    /* The pointer draws the selection, so the browser must not claim the gesture for panning. */
    touch-action: none;
    cursor: crosshair;
    user-select: none;
}

.cr-canvas {
    max-width: 100%;
    height: auto;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--surface);
}

.cr-selection {
    position: absolute;
    border: 2px solid var(--brand);
    /* The shade falls outside the box rather than over it, so the crop stays true to colour. */
    box-shadow: 0 0 0 9999px rgba(17, 24, 39, 0.45);
    cursor: move;
    pointer-events: none;
}

.cr-preview, .ph-preview {
    display: flex;
    justify-content: center;
    padding: 1rem;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--surface);
}

.cr-preview img, .ph-preview img {
    max-width: 100%;
    height: auto;
}

.fv-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(8.5rem, 1fr));
    gap: 0.85rem;
}

.fv-item {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.4rem;
    padding: 0.85rem 0.5rem;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--surface);
    text-align: center;
}

.fv-frame {
    display: flex;
    align-items: center;
    justify-content: center;
    /* One height for every cell, so the row does not step up and down with the icon sizes. */
    min-height: 6.5rem;
    padding: 0.35rem;
    border-radius: 10px;
}

.fv-frame img {
    max-width: 6rem;
    max-height: 6rem;
    image-rendering: pixelated;
}

.fv-caption {
    font-weight: 600;
    font-size: 0.85rem;
}

.fv-meta {
    font-size: 0.75rem;
    color: var(--ink-muted);
}

.ex-section + .ex-section {
    margin-top: 1.25rem;
}

.ex-section-title {
    font-size: 0.78rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--ink-muted);
    margin-bottom: 0.4rem;
}

.ex-rows {
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--surface);
    overflow: hidden;
}

.ex-row {
    display: grid;
    grid-template-columns: minmax(9rem, 1fr) minmax(10rem, 2fr);
    gap: 0.75rem;
    padding: 0.45rem 0.9rem;
    font-size: 0.85rem;
}

.ex-row + .ex-row {
    border-top: 1px solid var(--line);
}

.ex-row-name {
    font-weight: 600;
    overflow-wrap: anywhere;
}

.ex-row-value {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 0.8rem;
    overflow-wrap: anywhere;
}

.ex-location {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    padding: 0.85rem 1rem;
    border: 1px solid #fca5a5;
    border-radius: var(--radius);
    background: #fef2f2;
    color: #7f1d1d;
    margin-bottom: 1rem;
}

.ex-extras {
    padding: 0.85rem 1rem;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--brand-soft);
    font-size: 0.88rem;
}

/* The trailing block is the one entry in this list that is not a small metadata packet. */
.ex-extra-loud {
    font-weight: 650;
}

.ex-parts {
    padding: 0.85rem 1rem;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--brand-soft);
    margin-bottom: 1rem;
}

.ex-part-rows {
    list-style: none;
    padding-left: 0;
    margin-bottom: 0;
    border: 1px solid var(--line);
    border-radius: 10px;
    background: var(--surface);
    overflow: hidden;
}

.ex-part {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.6rem;
    padding: 0.5rem 0.85rem;
}

.ex-part + .ex-part {
    border-top: 1px solid var(--line);
}

.ex-part-name {
    font-weight: 600;
    font-size: 0.9rem;
    margin-right: auto;
    margin-bottom: 0;
    /* The checkbox is the control; clicking the name has to reach it. */
    cursor: pointer;
}

.ex-part-fixed .ex-part-name {
    cursor: default;
}

.ex-part-size, .ex-part-note {
    font-size: 0.78rem;
    color: var(--ink-muted);
    white-space: nowrap;
}

.ex-part-detail {
    display: block;
    font-weight: 400;
    font-size: 0.75rem;
    color: var(--ink-muted);
    overflow-wrap: anywhere;
}

/* ---------- Admin: request log ---------- */

/* The table is wide by nature — the page must not scroll sideways with it. */
.req-scroll {
    overflow-x: auto;
}

.req-table {
    width: 100%;
    margin-bottom: 0;
    border-collapse: collapse;
    font-size: 0.82rem;
}

.req-table th,
.req-table td {
    padding: 0.4rem 0.55rem;
    border-bottom: 1px solid var(--line);
    text-align: start;
    vertical-align: top;
    white-space: nowrap;
}

.req-table th {
    font-size: 0.72rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--ink-muted);
}

.req-table tbody tr:hover {
    background: var(--brand-soft);
}

.req-path {
    max-width: 24rem;
    white-space: normal;
    overflow-wrap: anywhere;
}

.req-detail {
    display: block;
    font-size: 0.72rem;
    color: var(--ink-muted);
    overflow-wrap: anywhere;
}

.req-agent {
    max-width: 18rem;
    overflow: hidden;
    text-overflow: ellipsis;
}

.req-num {
    font-variant-numeric: tabular-nums;
}

.req-2xx {
    color: #166534;
}

.req-3xx {
    color: #92400e;
}

.req-4xx,
.req-5xx {
    color: #b91c1c;
}

/* ---------- Admin: bans ---------- */

.ban-auto {
    display: inline-block;
    background: #fef2f2;
    color: #b91c1c;
    border-radius: 5px;
    padding: 0.05rem 0.4rem;
    font-size: 0.72rem;
    font-weight: 650;
    letter-spacing: 0.02em;
}

/* A disabled rule stays in the list — it is a decision somebody made, not a mistake to hide. */
.rule-off {
    opacity: 0.5;
}

.rule-off code {
    text-decoration: line-through;
}

/* ---------- Text re-encoder ---------- */

/* The three verdicts a conversion can carry. Colour is a hint, never the message: each one
   is spelled out in words beside it. */
.reenc-good {
    color: #166534;
}

.reenc-warn {
    color: #92400e;
}

.reenc-bad {
    color: #b91c1c;
}

.reenc-preview {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: 10px;
    padding: 0.8rem 1rem;
    max-height: 18rem;
    overflow: auto;
    /* Wraps rather than scrolling sideways: the reader is scanning for one wrong letter, and
       a horizontal scrollbar hides exactly the part they came to check. */
    white-space: pre-wrap;
    overflow-wrap: anywhere;
    font-size: 0.85rem;
    margin-bottom: 0;
}

/* The row the preview belongs to. */
.reenc-selected {
    background: var(--brand-soft);
}

.ex-part:not(.reenc-selected) {
    cursor: pointer;
}

/* ---------- Tool view counter ---------- */

.tool-views {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.4rem;
    margin: 2rem auto 0;
    padding-top: 1rem;
    max-width: 62rem;
    border-top: 1px solid var(--line);
    color: var(--ink-muted);
    font-size: 0.8rem;
    font-variant-numeric: tabular-nums;
}

/* ---------- Admin: tool usage ---------- */

/* A tool nobody has opened stays in the list — "which of these earns its place" is the
   question the screen exists to answer, and a missing row cannot answer it. */
.usage-idle {
    opacity: 0.55;
}

.usage-bar {
    display: inline-block;
    width: 6rem;
    height: 0.5rem;
    margin-right: 0.5rem;
    border-radius: 3px;
    background: var(--line);
    vertical-align: middle;
}

/* The filled part is drawn with a gradient stop rather than a child element: one element per
   row instead of two, on a table that can run to a hundred rows. */
.usage-bar {
    background: linear-gradient(to right, var(--brand) var(--share, 0%), var(--line) var(--share, 0%));
}

.usage-share {
    font-size: 0.75rem;
    color: var(--ink-muted);
}

/* ---------- Admin statistics ---------- */

.stat-block {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: 0.9rem 1rem 1rem;
    margin-bottom: 1rem;
    height: calc(100% - 1rem);
}

.stat-chart {
    display: flex;
    align-items: flex-end;
    gap: 2px;
    height: 140px;
    padding-top: 0.5rem;
}

.stat-col {
    flex: 1 1 0;
    display: flex;
    align-items: flex-end;
    height: 100%;
    /* Wide enough to stay a target for the tooltip when ninety days share the row. */
    min-width: 2px;
}

.stat-bar {
    width: 100%;
    /* A day with no traffic still draws a hairline, so the gap reads as "nothing" rather than
       as the chart having ended. */
    height: max(var(--h, 0%), 1px);
    background: var(--brand);
    border-radius: 2px 2px 0 0;
}

.stat-axis {
    display: flex;
    justify-content: space-between;
    gap: 0.5rem;
    margin-top: 0.4rem;
    font-size: 0.75rem;
    color: var(--ink-muted);
}

.stat-barcell {
    width: 7rem;
}

.stat-agent {
    font-size: 0.8rem;
    word-break: break-all;
}

.stat-tag {
    margin-left: 0.4rem;
    padding: 0.05rem 0.4rem;
    border-radius: 999px;
    font-size: 0.7rem;
    background: var(--brand-soft);
    color: var(--brand-dark);
    white-space: nowrap;
}

/* ---------- Viewport tool ---------- */

.vp-hero {
    background: linear-gradient(180deg, var(--brand-soft), var(--surface));
}

/* Large on purpose: this number gets read off a phone at arm's length, across a room, or
   through a screen share, and it is the one thing the page exists to say. */
.vp-size {
    font-size: clamp(2.5rem, 12vw, 4.5rem);
    font-weight: 700;
    line-height: 1.05;
    letter-spacing: -0.02em;
    font-variant-numeric: tabular-nums;
    color: var(--brand-dark);
}

.vp-unit {
    font-size: 0.8rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--ink-muted);
    margin-top: 0.35rem;
}

.vp-sub {
    margin-top: 0.6rem;
    color: var(--ink-muted);
    font-size: 0.9rem;
    font-variant-numeric: tabular-nums;
}

.vp-detail {
    font-size: 0.72rem;
    color: var(--ink-muted);
}

/* ---------- Search and favourites ---------- */

.app-search {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    background: transparent;
    border: 0;
}

.app-search-key {
    border: 1px solid var(--line);
    border-radius: 6px;
    padding: 0 0.35rem;
    font-size: 0.72rem;
    color: var(--ink-muted);
    background: var(--canvas);
}

/* The card and its star are siblings in a row rather than one inside the other: a button inside
   an anchor is invalid markup, and overlaying one on the card would put it on top of text whose
   length nobody controls. */
.tool-card-wrap {
    display: flex;
    align-items: stretch;
    gap: 0.25rem;
}

.tool-card-wrap > .tool-card {
    flex: 1 1 auto;
    min-width: 0;
}

.tool-fav {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2rem;
    padding: 0;
    border: 0;
    border-radius: 10px;
    background: transparent;
    /* Present but quiet: eighty-seven of these are on the home page at once, and at full strength
       they would read as decoration on every card rather than as a control. */
    color: var(--ink-muted);
    opacity: 0.4;
    transition: opacity .15s ease, color .15s ease, background-color .15s ease;
}

.tool-fav:hover,
.tool-fav:focus-visible {
    opacity: 1;
    background: var(--brand-soft);
}

.tool-fav.is-on {
    color: var(--brand);
    opacity: 1;
}

/* The icon is drawn with fill="none" as an attribute; a CSS fill outranks a presentation
   attribute, so one class turns the same outline into a solid star. */
.tool-fav.is-on .fbc-icon,
.tool-fav-page.is-on .fbc-icon {
    fill: currentColor;
}

.crumb-bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 0.75rem;
    margin-bottom: 1rem;
}

.crumb-bar .breadcrumb {
    margin-bottom: 0;
}

.tool-fav-page {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.2rem 0.7rem;
    border: 1px solid var(--line);
    border-radius: 999px;
    background: var(--surface);
    color: var(--ink-muted);
    font-size: 0.8rem;
}

.tool-fav-page:hover,
.tool-fav-page:focus-visible,
.tool-fav-page.is-on {
    border-color: var(--brand);
    color: var(--brand);
}

/* ---------- Search dialog ---------- */

.pal-backdrop {
    position: fixed;
    inset: 0;
    /* Above the sticky navigation bar, which Bootstrap puts at 1020. */
    z-index: 1080;
    display: flex;
    justify-content: center;
    align-items: flex-start;
    padding: 10vh 1rem 1rem;
    background: rgba(17, 24, 39, 0.45);
}

/* The hidden attribute means display:none, and the rule above would otherwise outrank it. */
.pal-backdrop[hidden] {
    display: none;
}

.pal {
    width: min(42rem, 100%);
    max-height: 72vh;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    background: var(--surface);
    border-radius: var(--radius);
    box-shadow: 0 24px 60px rgba(17, 24, 39, 0.35);
}

.pal-head {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.8rem 1rem;
    border-bottom: 1px solid var(--line);
}

.pal-glass {
    color: var(--ink-muted);
}

.pal-input {
    flex: 1 1 auto;
    min-width: 0;
    border: 0;
    outline: 0;
    background: transparent;
    color: var(--ink);
    font-size: 1.05rem;
}

/* The background is spelled out because Bootstrap's own kbd rule paints it near-black, which
   against a muted foreground is a key cap nobody can read. */
.pal-esc,
.pal-foot kbd {
    border: 1px solid var(--line);
    border-radius: 6px;
    padding: 0 0.35rem;
    font-size: 0.72rem;
    color: var(--ink-muted);
    background: var(--canvas);
}

.pal-list {
    flex: 1 1 auto;
    overflow-y: auto;
    list-style: none;
    margin: 0;
    padding: 0.4rem;
}

.pal-heading {
    padding: 0.45rem 0.6rem 0.25rem;
    font-size: 0.72rem;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--ink-muted);
}

.pal-item {
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
    padding: 0.5rem 0.6rem;
    border-radius: 10px;
    cursor: pointer;
}

.pal-item.is-active {
    background: var(--brand-soft);
}

.pal-item-head {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.pal-item-title {
    font-weight: 600;
}

.pal-item-group {
    font-size: 0.78rem;
    color: var(--ink-muted);
}

.pal-item-star {
    color: var(--brand);
    fill: currentColor;
}

.pal-item-desc {
    font-size: 0.82rem;
    color: var(--ink-muted);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.pal-empty {
    padding: 1.3rem 0.6rem;
    text-align: center;
    color: var(--ink-muted);
}

.pal-foot {
    display: flex;
    flex-wrap: wrap;
    gap: 1rem;
    padding: 0.55rem 1rem;
    border-top: 1px solid var(--line);
    font-size: 0.78rem;
    color: var(--ink-muted);
}

/* The page behind the dialog must not scroll under it. */
body.pal-open {
    overflow: hidden;
}

/* ---------- Prose pages ---------- */

.prose-page {
    max-width: 48rem;
}

.prose-page section + section {
    margin-top: 2rem;
}

.prose-page h2 {
    margin-bottom: 0.6rem;
}

.prose-page p,
.prose-page li {
    color: var(--ink-muted);
}

.prose-page ul {
    padding-left: 1.2rem;
}

.prose-page li + li {
    margin-top: 0.35rem;
}

/* ---------- What your browser reveals ---------- */

.who-section + .who-section {
    margin-top: 1.25rem;
}

.who-section-title {
    color: var(--ink-muted);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    font-size: 0.72rem;
    margin-bottom: 0.5rem;
}

.who-value {
    font-variant-numeric: tabular-nums;
}

/* The user agent and the referrer are routinely longer than the column, and they are read as
   one string — so they wrap anywhere rather than pushing the page sideways. */
.who-wrap {
    overflow-wrap: anywhere;
    font-size: 0.85rem;
}

.who-note {
    margin-top: 1rem;
    margin-bottom: 0;
}
