/* Oversight, site specific styling on top of Bulma 1.0.4 dark.
   Bulma, Font Awesome 6 Pro, flatpickr and the GEN fonts all come from
   cdn.gen.network. Only what is genuinely ours lives here. */

:root {
    /* GEN primary, the same indigo GENUK uses */
    --bulma-primary-h: 248deg;
    --bulma-primary-s: 55%;
    --bulma-primary-l: 32%;
    --bulma-link-h: 186deg;
    --bulma-link-s: 45%;
    --bulma-link-l: 55%;

    --bulma-family-primary: 'Cantarell', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
    --bulma-family-code: 'JetBrainsMono', ui-monospace, Menlo, Consolas, monospace;

    --gen-gradient: linear-gradient(to right, #000000, #221c54);
    --gen-ink: #e8ecf2;
    --gen-dim: #8a94a3;
    --gen-edge: #242b36;
    --gen-panel: #131821;
    --gen-panel-2: #0d1118;
    --gen-page: #080b10;

    --st-ok: #3fbf5f;
    --st-warn: #e8ab22;
    --st-crit: #e03b30;
    --st-unknown: #5f6a78;
    --st-stale: #9b86dd;
    --st-paused: #3f8fd6;
}

html { background: var(--gen-page); }
/* A column, so the content takes the height and the footer sits on the bottom edge
   rather than halfway up a short page with the empty page colour hanging under it. */
body {
    background: var(--gen-page);
    color: var(--gen-ink);
    min-height: 100vh;
    display: flex;
    flex-direction: column;
}
body > main { flex: 1 0 auto; }

/* ---- Chrome ---------------------------------------------------------- */

.navbar.gen-bar {
    background: var(--gen-gradient);
    border-bottom: 1px solid var(--gen-edge);
}
.navbar.gen-bar .navbar-item,
.navbar.gen-bar .navbar-link { color: #cfd6e0; }
.navbar.gen-bar a.navbar-item:hover,
.navbar.gen-bar a.navbar-item.is-active,
.navbar.gen-bar .navbar-link.is-active {
    background: rgba(255, 255, 255, .08);
    color: #fff;
}
@font-face {
    font-family: 'Orbitron';
    src: url('/fonts/Orbitron-VariableFont_wght.ttf') format('truetype');
    font-weight: 400 900;
    font-display: block;
}
/* The logo stands in for the O. Orbitron's capitals are 0.72em tall, so this size gives
   about 23px of capital beside the 24px the logo's square fills of its 28px box, and at
   a line height of 1 their centres land within a pixel of each other. */
.gen-brand {
    font-family: 'Orbitron', var(--bulma-family-code);
    font-weight: 500;   /* to match the stroke of the logo's square */
    font-size: 1.98rem;
    line-height: 1;
    letter-spacing: -.5px;
    color: #fff !important;
}
/* Bulma puts a 12px gap between everything in a navbar item. Here the logo is a letter,
   so it takes none, and the logo's own margin is the space before the V. */
.navbar.gen-bar .gen-brand { gap: 0; }
.gen-brand img { margin-right: -1px; }
/* Orbitron's capitals sit a little below the middle of their line box, so centring the box
   leaves them low against the logo. */
.gen-brand span { position: relative; top: -1px; }

.gen-foot {
    color: var(--gen-dim);
    font-size: .75rem;
    padding: .45rem 1.5rem;
    border-top: 1px solid var(--gen-edge);
}

/* ---- Panels ---------------------------------------------------------- */

.gen-panel {
    background: var(--gen-panel);
    border: 1px solid var(--gen-edge);
    border-radius: 6px;
}
.gen-panel > .gen-panel-head {
    padding: .7rem 1rem;
    border-bottom: 1px solid var(--gen-edge);
    background: var(--gen-panel-2);
    border-radius: 6px 6px 0 0;
    display: flex;
    align-items: center;
    gap: .6rem;
}
.gen-panel > .gen-panel-head .gen-panel-title {
    font-weight: 600;
    letter-spacing: .3px;
}
.gen-panel > .gen-panel-body { padding: 1rem; }

/* The editor's Save row. Sticky to the bottom of the window while the form is in view,
   so a long sensor form does not need scrolling to the end for every change, and it
   drops back into place under the last panel rather than covering what follows. */
.gen-savebar {
    position: sticky;
    bottom: 0;
    z-index: 5;
    height: 3.75rem;
    align-items: center;
    background: var(--gen-page);
    border-top: 1px solid var(--gen-edge);
}

.gen-hint { color: var(--gen-dim); font-size: .8rem; }
.gen-mono { font-family: var(--bulma-family-code); }

/* ---- State ----------------------------------------------------------- */

.st { font-weight: 600; }
.st-OK { color: var(--st-ok); }
.st-WARN { color: var(--st-warn); }
.st-CRIT { color: var(--st-crit); }
.st-UNKNOWN { color: var(--st-unknown); }
.st-STALE { color: var(--st-stale); }
.st-PAUSED { color: var(--st-paused); }

.gen-dot {
    display: inline-block;
    width: .6rem;
    height: .6rem;
    border-radius: 50%;
    background: currentColor;
    box-shadow: 0 0 6px currentColor;
    flex: 0 0 auto;
}

.gen-tag {
    display: inline-block;
    font-size: .68rem;
    font-weight: 600;
    letter-spacing: .5px;
    padding: .12rem .5rem;
    border-radius: 10px;
    border: 1px solid currentColor;
    white-space: nowrap;
}

/* ---- Tree ------------------------------------------------------------ */

.gen-tree { padding: .4rem 0 .6rem; font-size: .84rem; }
.gen-tree ul { list-style: none; margin: 0; padding: 0; }
.gen-tree ul ul {
    margin-left: .95rem;
    padding-left: .55rem;
    border-left: 1px solid var(--gen-edge);
}

.gen-row {
    display: flex;
    align-items: center;
    gap: .3rem;
    border-left: 2px solid transparent;
    padding-right: .6rem;
}
.gen-row:hover { background: rgba(255, 255, 255, .05); }
.gen-row.is-current {
    background: rgba(95, 158, 160, .14);
    border-left-color: cadetblue;
}
.gen-row.is-off { opacity: .45; }

.gen-node {
    display: flex;
    align-items: center;
    gap: .45rem;
    padding: .3rem 0;
    color: var(--gen-ink);
    text-decoration: none;
    flex: 1 1 auto;
    min-width: 0;
}
.gen-node:hover { color: #fff; }
.gen-node .gen-node-icon { width: 1.1rem; text-align: center; color: var(--gen-dim); flex: 0 0 auto; }
.gen-node .gen-node-img { width: 16px; height: 16px; object-fit: contain; flex: 0 0 auto; }
.gen-selicon { width: 22px; height: 22px; object-fit: contain; flex: 0 0 auto; }
.gen-node .gen-node-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.gen-node .gen-node-meta {
    color: var(--gen-dim);
    font-size: .7rem;
    margin-left: auto;
    padding-left: .5rem;
    flex: 0 0 auto;
}

/* The twisty is a label for a checkbox holding the open state, so the tree
   remembers what is expanded across a page load without any script behind it. */
.gen-twist {
    width: .95rem;
    text-align: center;
    color: var(--gen-dim);
    cursor: pointer;
    flex: 0 0 auto;
    font-size: .62rem;
    user-select: none;
}
.gen-twist.is-leaf { visibility: hidden; cursor: default; }
.gen-open { position: absolute; opacity: 0; pointer-events: none; }
.gen-open ~ ul { display: none; }
.gen-open:checked ~ ul { display: block; }
.gen-open ~ .gen-row .gen-twist .fa-chevron-down { display: none; }
.gen-open:checked ~ .gen-row .gen-twist .fa-chevron-right { display: none; }
.gen-open:checked ~ .gen-row .gen-twist .fa-chevron-down { display: inline-block; }

.gen-treewrap { max-height: calc(100vh - 210px); overflow: auto; }
/* ---- Forms ----------------------------------------------------------- */

.gen-panel .input,
.gen-panel .textarea,
.gen-panel .select select {
    background: var(--gen-panel-2);
    border-color: var(--gen-edge);
    color: var(--gen-ink);
}
.gen-panel .input::placeholder { color: #5a6472; }
.gen-panel label.label { color: var(--gen-ink); font-size: .82rem; }
.gen-fieldnote { color: var(--gen-dim); font-size: .72rem; margin-top: .2rem; }

.gen-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: .9rem 1.2rem;
}

table.gen-table { width: 100%; border-collapse: collapse; }
table.gen-table th,
table.gen-table td {
    text-align: left;
    padding: .45rem .6rem;
    border-bottom: 1px solid var(--gen-edge);
    vertical-align: middle;
}
table.gen-table th { color: var(--gen-dim); font-weight: 600; font-size: .75rem; letter-spacing: .4px; }
table.gen-table tr:last-child td { border-bottom: 0; }
table.gen-table tbody tr:hover td { background: rgba(255, 255, 255, .03); }

/* ---- Availability -------------------------------------------------- */
.gen-avail {
    display: flex;
    flex-direction: column;
    gap: .4rem;
    padding: .7rem .9rem;
    margin-bottom: 1rem;
    background: var(--gen-panel-2);
    border: 1px solid var(--gen-edge);
    border-radius: 6px;
}
.gen-availrow { display: flex; align-items: center; gap: .7rem; }
.gen-availwin { width: 2.4rem; color: var(--gen-dim); font-size: .75rem; font-weight: 600; }
.gen-availbar {
    flex: 1 1 auto;
    display: flex;
    height: .6rem;
    border-radius: 3px;
    overflow: hidden;
    background: var(--st-unknown);
}
.gen-availbar span { height: 100%; }
.gen-availdown { width: 6.5rem; text-align: right; font-size: .8rem; font-weight: 600; color: var(--gen-dim); }
.gen-availdown.st-CRIT { color: var(--st-crit); }
/* Fixed, so the bars all end at the same place however long the note beside them is. */
.gen-availrow .gen-hint { width: 13rem; flex: 0 0 auto; }

.gen-modal .modal-card-head,
.gen-modal .modal-card-foot {
    background: var(--gen-panel-2);
    border-color: var(--gen-edge);
}
.gen-modal .modal-card-body { background: var(--gen-panel); }
.gen-modal .modal-card-title { color: var(--gen-ink); font-size: 1rem; }

/* ---- Compatibility --------------------------------------------------- */
/* login.php and probes.php still use the first cut markup. These keep them
   legible on the new shell until each is rebuilt in its own right. */

.panel {
    background: var(--gen-panel);
    border: 1px solid var(--gen-edge);
    border-radius: 6px;
    padding: 1.25rem;
    margin-bottom: 1.25rem;
    box-shadow: none;
}
.panel h1 { font-size: 1.35rem; margin-bottom: .75rem; font-weight: 600; }
.panel h2 { font-size: 1rem; margin-bottom: .6rem; font-weight: 600; }
table.data { width: 100%; border-collapse: collapse; }
table.data th, table.data td {
    text-align: left;
    padding: .45rem .6rem;
    border-bottom: 1px solid var(--gen-edge);
}
table.data th { color: var(--gen-dim); font-weight: 600; }
.note { color: var(--gen-dim); }
.error { color: var(--st-crit); }
.ok { color: var(--st-ok); }
tr.dim td { opacity: .5; }
.state {
    font-size: .68rem;
    font-weight: 600;
    letter-spacing: .4px;
    padding: .12rem .5rem;
    border-radius: 10px;
    border: 1px solid currentColor;
}
.state.OK { color: var(--st-ok); }
.state.WARN { color: var(--st-warn); }
.state.CRIT { color: var(--st-crit); }
.state.UNKNOWN { color: var(--st-unknown); }
.state.STALE { color: var(--st-stale); }
.state.PAUSED { color: var(--st-paused); }
.panel label { display: block; margin-bottom: .75rem; }
.panel input[type=text], .panel input[type=password], .panel select, .panel textarea {
    background: var(--gen-panel-2);
    border: 1px solid var(--gen-edge);
    border-radius: 4px;
    color: var(--gen-ink);
    padding: .5rem;
    font-size: .875rem;
    max-width: 340px;
}
.panel button {
    background: hsl(var(--bulma-primary-h), var(--bulma-primary-s), var(--bulma-primary-l));
    color: #fff;
    border: 0;
    border-radius: 4px;
    padding: .55rem 1.1rem;
    font-size: .875rem;
    cursor: pointer;
}
.panel button.link {
    background: none;
    color: hsl(var(--bulma-link-h), var(--bulma-link-s), var(--bulma-link-l));
    padding: 0 .35rem;
    font-size: .8rem;
}
.panel button.link:hover { text-decoration: underline; }

/* ---- Controls -------------------------------------------------------- */

.gen-panel input[type=checkbox]:not(.gen-open),
.gen-modal input[type=checkbox] {
    appearance: none;
    -webkit-appearance: none;
    width: 1rem;
    height: 1rem;
    border: 1px solid #3a4453;
    border-radius: 3px;
    background: var(--gen-panel-2);
    vertical-align: -.18rem;
    cursor: pointer;
    position: relative;
    flex: 0 0 auto;
}
.gen-panel input[type=checkbox]:not(.gen-open):checked,
.gen-modal input[type=checkbox]:checked {
    background: cadetblue;
    border-color: cadetblue;
}
.gen-panel input[type=checkbox]:not(.gen-open):checked::after,
.gen-modal input[type=checkbox]:checked::after {
    content: '';
    position: absolute;
    left: .3rem;
    top: .09rem;
    width: .25rem;
    height: .55rem;
    border: solid #0b0e13;
    border-width: 0 2px 2px 0;
    transform: rotate(45deg);
}
.gen-panel .checkbox,
.gen-modal .checkbox {
    color: var(--gen-ink);
    display: inline-flex;
    align-items: flex-start;
    line-height: 1.35;
    gap: .35rem;
}
.gen-panel .checkbox.is-block,
.gen-modal .checkbox.is-block { display: flex; margin-bottom: .3rem; }
.gen-panel .checkbox:hover,
.gen-modal .checkbox:hover { color: #fff; }

.gen-panel .select:not(.is-multiple):not(.is-loading)::after { border-color: cadetblue; }

.notification .icon { vertical-align: -.25rem; margin-right: .2rem; }

/* ---- Dashboard: the wheel -------------------------------------------- */

/* The dashboard is the screen that sells the system, so it takes more of the width: half
   Bulma's side padding. Bulma sets these on .section itself, hence the longer selector. */
main.section:has(> .gen-dash) {
    --bulma-section-padding: 3rem .75rem;
    --bulma-section-padding-desktop: 3rem 1.5rem;
}
/* A faint network picture behind the whole panel. On a pseudo element so its opacity can
   be set without fading what sits on top, and so a photograph can replace the SVG by
   changing the url alone. */
.gen-panel.gen-dash {
    position: relative;
    isolation: isolate;
    box-shadow: 0 10px 30px rgba(0, 0, 0, .45);
}
.gen-panel.gen-dash::before {
    content: '';
    position: absolute;
    inset: 0;
    z-index: -1;
    border-radius: inherit;
    background: url('/images/dash-bg.svg') center / cover no-repeat;
    opacity: .14;
    pointer-events: none;
}

.gen-wheelwrap {
    position: relative;
    width: 100%;
    /* As big as the height left over once the bar, panel head, tabs, padding and
       footer are taken out, about 15rem between them. A fixed pixel cap left a large
       screen with a small wheel and a band of nothing under it. The floor stops a
       short window squeezing it to nothing; width still limits it on a phone. */
    max-width: max(22rem, calc(100vh - 15rem));
    margin: 0 auto;
    container-type: inline-size;   /* so the centre text can be sized to the wheel */
}
.gen-wheelwrap svg { display: block; width: 100%; height: auto; }

.gen-seg {
    stroke: none;
    cursor: pointer;
    transition: opacity .12s;
}
.gen-seg:hover { opacity: .8; }
.gen-seg.is-sel { stroke: #fff; stroke-width: 1.4; }

/* The glow under a critical device: it swells out from the segment and fades. Only the
   half outside the segment shows, as the segment itself is drawn over it. */
.gen-pulse {
    fill: #e03b30;
    stroke: #e03b30;
    stroke-linejoin: round;
    pointer-events: none;
    animation: gen-pulse 1.6s ease-out infinite;
}
@keyframes gen-pulse {
    0%   { stroke-width: 0;  stroke-opacity: .7; }
    100% { stroke-width: 12; stroke-opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
    .gen-pulse { animation: none; stroke-width: 0; }
}

/* The centre is the focus of the wheel and the way back up out of it. */
.gen-wheelmid {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    width: 31%;
    text-align: center;
    pointer-events: none;
}
.gen-wheelmid .gen-midname {
    font-weight: 600;
    font-size: .82rem;
    line-height: 1.2;
    overflow: hidden;
    text-overflow: ellipsis;
}
/* A 2:1 box across most of the centre, which with the state line under it stays inside
   the hole at any wheel size. The logo is fitted within it whatever its own shape. */
.gen-wheelmid .gen-midlogo {
    width: 78%;
    margin: 0 auto .2rem;
    aspect-ratio: 2 / 1;
}
.gen-wheelmid .gen-midlogo img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: contain;
}
.gen-wheelmid .gen-midstate { font-size: .68rem; font-weight: 600; letter-spacing: .5px; }
/* On the dashboard the state is the headline, so it scales with the wheel rather than
   staying a fixed size that a large screen turns into a footnote. */
.gen-wheelwrap .gen-wheelmid .gen-midstate { font-size: 2.4cqw; line-height: 1.15; }
.gen-wheelmid .gen-midup {
    pointer-events: auto;
    margin-top: .3rem;
    background: none;
    border: 1px solid var(--gen-edge);
    border-radius: 10px;
    color: var(--gen-dim);
    font-size: .64rem;
    padding: .1rem .45rem;
    cursor: pointer;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.gen-wheelmid .gen-midup:hover { color: #fff; border-color: cadetblue; }

.gen-legendstates {
    display: flex;
    flex-wrap: wrap;
    gap: .3rem;
    font-size: .74rem;
    color: var(--gen-dim);
}
.gen-scount {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    background: var(--gen-panel-2);
    border: 1px solid var(--gen-edge);
    border-radius: 10px;
    padding: .12rem .55rem;
    color: var(--gen-dim);
    font-family: inherit;
    font-size: .72rem;
    cursor: pointer;
}
.gen-scount:hover { color: #fff; border-color: cadetblue; }

.gen-chips { display: flex; flex-wrap: wrap; gap: .35rem; margin-bottom: .8rem; }
.gen-chip {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    background: var(--gen-panel-2);
    border: 1px solid var(--gen-edge);
    border-radius: 10px;
    padding: .18rem .6rem;
    color: var(--gen-dim);
    font-family: inherit;
    font-size: .73rem;
    cursor: pointer;
}
.gen-chip:hover { color: #fff; }
.gen-chip.is-on { background: cadetblue; border-color: cadetblue; color: #06080b; font-weight: 600; }

/* ---- Dashboard: the chart -------------------------------------------- */

.gen-ranges { display: inline-flex; gap: .25rem; }
.gen-range {
    background: var(--gen-panel-2);
    border: 1px solid var(--gen-edge);
    color: var(--gen-dim);
    border-radius: 4px;
    font-size: .72rem;
    padding: .2rem .55rem;
    cursor: pointer;
    font-family: inherit;
}
.gen-range:hover { color: #fff; border-color: cadetblue; }
.gen-range.is-on { background: cadetblue; border-color: cadetblue; color: #06080b; font-weight: 600; }

.gen-panel .input.gen-when {
    width: 12.5rem;
    font-size: .72rem;
    height: auto;
    padding: .15rem .4rem;
    color-scheme: dark;
}

.gen-chartwrap { position: relative; }
.gen-chartwrap canvas { display: block; width: 100%; }
.gen-chartfoot { text-align: right; font-size: .7rem; margin-top: .2rem; }

.gen-tip {
    position: absolute;
    z-index: 5;
    pointer-events: none;
    background: rgba(8, 11, 16, .96);
    border: 1px solid var(--gen-edge);
    border-radius: 5px;
    padding: .45rem .55rem;
    font-size: .74rem;
    min-width: 13rem;
    box-shadow: 0 6px 20px rgba(0, 0, 0, .5);
}
.gen-tiptime { color: var(--gen-dim); font-size: .68rem; margin-bottom: .3rem; }
.gen-tiprow { display: flex; align-items: center; gap: .4rem; padding: .06rem 0; }
.gen-tiplabel { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.gen-tipval { margin-left: auto; font-family: var(--bulma-family-code); font-size: .72rem; }

.gen-swatch { width: .7rem; height: .22rem; border-radius: 2px; flex: 0 0 auto; }

.gen-legend { margin-top: .2rem; }
.gen-leg {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    font-size: .75rem;
    color: var(--gen-dim);
    cursor: pointer;
    padding: .12rem 0;
}
.gen-leg.is-on { color: var(--gen-ink); }
.gen-leg:hover { color: #fff; }
.gen-leg .gen-unit {
    font-size: .64rem;
    border: 1px solid var(--gen-edge);
    border-radius: 8px;
    padding: 0 .35rem;
    color: var(--gen-dim);
}

.gen-legendbar {
    display: flex;
    align-items: center;
    gap: .5rem;
    margin-top: .7rem;
    padding-top: .7rem;
    border-top: 1px solid var(--gen-edge);
}
.gen-panel .input.gen-legfilter {
    width: 14rem;
    font-size: .74rem;
    height: auto;
    padding: .2rem .5rem;
}
.gen-legendbar .gen-hint { margin-left: auto; font-size: .72rem; }

.gen-leggroup {
    margin: .5rem 0 0;
    padding-left: .6rem;
    border-left: 2px solid var(--gen-edge);
}
.gen-leghead {
    font-size: .68rem;
    letter-spacing: .5px;
    text-transform: uppercase;
    color: var(--gen-dim);
    margin-bottom: .1rem;
}
.gen-leggroup .gen-leg { margin-right: 1.1rem; }

.gen-problems { margin-top: 1rem; border-top: 1px solid var(--gen-edge); padding-top: .6rem; }
.gen-problems .gen-table td { padding: .3rem .5rem; font-size: .8rem; }

/* ---- Dashboard: the panes either side of the wheel ------------------- */

/* 20 / 60 / 20. The panes stretch to the wheel's height and scroll inside it, and their
   cap matches the wheel's own, so a long alarm list cannot push the page down. Below a
   desktop width the wheel comes first and the panes stack under it. */
.gen-wheelgrid {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 3fr) minmax(0, 1fr);
    grid-template-areas: "tree wheel alarm";
    gap: 1rem;
}
.gen-wheelgrid[hidden] { display: none; }
.gen-wheelgrid > .gen-wheelwrap { grid-area: wheel; align-self: center; }
.gen-sidetree  { grid-area: tree; }
.gen-sidealarm { grid-area: alarm; }
@media screen and (max-width: 1023px) {
    .gen-wheelgrid { grid-template-columns: minmax(0, 1fr); grid-template-areas: "wheel" "alarm" "tree"; }
}

.gen-panel.gen-side {
    display: flex;
    flex-direction: column;
    min-height: 0;
    max-height: max(22rem, calc(100vh - 15rem));
    background: rgba(13, 17, 24, .72);
    backdrop-filter: blur(3px);
    box-shadow: 0 6px 18px rgba(0, 0, 0, .45), inset 0 1px 0 rgba(255, 255, 255, .04);
}
.gen-side > .gen-panel-head { padding: .5rem .75rem; gap: .4rem; }
.gen-side > .gen-panel-head .gen-panel-title { font-size: .82rem; }
.gen-sidebody { flex: 1 1 auto; min-height: 0; overflow: auto; padding: .5rem; }
.gen-sidebody.gen-tree { padding: .4rem .2rem; font-size: .8rem; }
.gen-sidebody.gen-tree .gen-node { padding: .22rem 0; }

.gen-alarm {
    --c: var(--st-unknown);
    display: block;
    margin-bottom: .4rem;
    padding: .4rem .6rem;
    border: 1px solid var(--gen-edge);
    border-left: 3px solid var(--c);
    border-radius: 5px;
    background: linear-gradient(90deg, color-mix(in srgb, var(--c) 16%, transparent), transparent 75%);
    color: var(--gen-ink);
    font-size: .78rem;
    line-height: 1.3;
}
.gen-alarm:hover { color: #fff; border-color: color-mix(in srgb, var(--c) 60%, var(--gen-edge)); border-left-color: var(--c); }
.gen-alarm.is-CRIT    { --c: var(--st-crit); }
.gen-alarm.is-WARN    { --c: var(--st-warn); }
.gen-alarm.is-STALE   { --c: var(--st-stale); }
.gen-alarm-top { display: flex; align-items: center; gap: .4rem; }
.gen-alarm-name { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.gen-alarm-age { margin-left: auto; color: var(--gen-dim); font-size: .7rem; flex: 0 0 auto; }
.gen-alarm-where {
    display: block;
    margin-top: .1rem;
    padding-left: 1rem;
    color: var(--gen-dim);
    font-size: .7rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.gen-alarm-where .st-CRIT, .gen-alarm-where .st-WARN, .gen-alarm-where .st-STALE, .gen-alarm-where .st-UNKNOWN {
    font-weight: 600;
    font-size: .64rem;
    letter-spacing: .4px;
    margin-left: .2rem;
}
.gen-allclear {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: .5rem;
    height: 100%;
    min-height: 8rem;
    color: var(--st-ok);
    font-weight: 600;
    letter-spacing: .5px;
}
.gen-allclear i { font-size: 2rem; filter: drop-shadow(0 0 8px var(--st-ok)); }

/* ---- Dashboard: tabs, log and one poll ------------------------------- */

.gen-tabs {
    display: flex;
    gap: .15rem;
    padding: 0 .6rem;
    border-bottom: 1px solid var(--gen-edge);
    background: var(--gen-panel-2);
}
.gen-tab {
    background: none;
    border: 1px solid transparent;
    border-bottom: 0;
    border-radius: 4px 4px 0 0;
    margin-top: .3rem;
    color: var(--gen-dim);
    font-family: inherit;
    font-size: .78rem;
    padding: .5rem .8rem;
    cursor: pointer;
}
.gen-tab i { margin-right: .3rem; opacity: .8; }
.gen-tab:hover { color: #fff; }
/* Lifted to the panel's own shade and edged, rather than underlined. */
.gen-tab.is-on { color: var(--gen-ink); background: var(--gen-panel); border-color: var(--gen-edge); }
/* The refresh bar under the tabs. stampLive() empties it and grows it over the interval. */
.gen-tick { height: 2px; background: var(--gen-panel-2); overflow: hidden; }
.gen-tick > div { height: 100%; width: 0; background: #3f8fd6; }

.gen-histbar { display: flex; align-items: center; gap: .4rem; flex-wrap: wrap; margin-bottom: .7rem; }
#tab-hist [hidden] { display: none !important; }
/* The log and data tables scroll inside the panel; fitScroll() sets the height. */
.gen-scroll { overflow: auto; }
.gen-scroll table th { position: sticky; top: 0; z-index: 1; background: var(--gen-panel); }

table.gen-log td { padding: .3rem .5rem; font-size: .78rem; }
table.gen-log tbody tr { cursor: pointer; }
.gen-logrow:hover td { background: rgba(95, 158, 160, .1); }
.gen-logfoot { display: flex; align-items: center; gap: .6rem; margin-top: .6rem; }
.gen-logfoot .gen-hint { margin-right: auto; }
#tab-log { max-height: 62vh; overflow: auto; }

.gen-rescard { width: min(920px, 94vw); }
.gen-raw {
    background: var(--gen-page);
    border: 1px solid var(--gen-edge);
    border-radius: 4px;
    padding: .6rem .7rem;
    font-family: var(--bulma-family-code);
    font-size: .72rem;
    line-height: 1.45;
    color: #b9c2cf;
    max-height: 22rem;
    overflow: auto;
    white-space: pre-wrap;
    word-break: break-word;
}

.gen-panel-head #wheelcrumb { font-size: .74rem; }
.gen-panel-head #wheelcrumb a { color: var(--gen-dim); }
.gen-panel-head #wheelcrumb a:hover { color: cadetblue; }
#wheelside .gen-table td { padding: .35rem .5rem; font-size: .8rem; }

.gen-seglab {
    /* AdventPro is a variable font, but the CDN's @font-face pins it to normal, so
       asking for font-weight 600 gets a synthesised bold rather than the weight axis.
       font-variation-settings reaches the real axis. */
    font-family: 'AdventPro', var(--bulma-family-primary);
    font-weight: normal;
    font-variation-settings: 'wght' 640;
    pointer-events: none;
    letter-spacing: .01em;
}

.gen-pill {
    display: inline-block;
    min-width: 1.1rem;
    margin-left: .35rem;
    padding: 0 .35rem;
    border-radius: 8px;
    font-size: .66rem;
    font-weight: 700;
    background: currentColor;
}
.gen-pill.st-CRIT, .gen-pill.st-WARN, .gen-pill.st-STALE, .gen-pill.st-UNKNOWN { color: inherit; }
.gen-pill:not(:empty) { color: #0b0e13; }
.gen-pill.st-CRIT:not(:empty)    { background: var(--st-crit); }
.gen-pill.st-WARN:not(:empty)    { background: var(--st-warn); }
.gen-pill.st-STALE:not(:empty)   { background: var(--st-stale); }
.gen-pill.st-UNKNOWN:not(:empty) { background: var(--st-unknown); }
.gen-pill.st-PAUSED:not(:empty)  { background: var(--st-paused); }

/* Bulma works the text colour out from the primary, and against this indigo it
   settles on something close to black. The button is the one on every form. */
.button.is-primary,
.button.is-primary:hover,
.button.is-primary:focus,
.button.is-primary:active {
    color: #fff;
    background-color: hsl(var(--bulma-primary-h), var(--bulma-primary-s), var(--bulma-primary-l));
    border-color: transparent;
}
.button.is-primary:hover { background-color: hsl(var(--bulma-primary-h), var(--bulma-primary-s), 40%); }
.button.is-dark { color: var(--gen-ink); background-color: var(--gen-panel-2); border-color: var(--gen-edge); }
.button.is-dark:hover { color: #fff; border-color: cadetblue; }

/* A sensor type's help: a button that stands out from the dark ones around it, and a box in a
   different shade with a sky blue edge, so it is plain where the help starts and ends. */
.button.gen-help { color: #0d1118; background-color: skyblue; border-color: #5aa9cf; font-weight: 600; }
.button.gen-help:hover,
.button.gen-help:focus { color: #0d1118; background-color: #a9dcf0; border-color: skyblue; }
.gen-helpbox {
    background: #0f1c2b;
    border: 1px solid #2a4560;
    border-left: 3px solid skyblue;
    border-radius: 6px;
    padding: 1rem;
    font-size: .85rem;
}
.gen-helpbox table.gen-table td { vertical-align: top; }

/* The icon picker. The icons declare their size in millimetres, so every img here is given
   its box and told to fit it, or each would render at 150px or so. */
.gen-iconbtn { justify-content: flex-start; }
.gen-iconbtn img { width: 20px; height: 20px; object-fit: contain; margin-right: .5rem; }
.gen-icongrid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(72px, 1fr));
    gap: .5rem;
}
.gen-iconhead { color: var(--gen-dim); font-size: .72rem; margin: .9rem 0 .4rem; }
.gen-iconopt {
    height: 64px;
    padding: .45rem;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--gen-panel-2);
    border: 1px solid var(--gen-edge);
    border-radius: 6px;
    color: var(--gen-dim);
    font-size: .75rem;
    cursor: pointer;
}
.gen-iconopt img { width: 100%; height: 100%; object-fit: contain; }
.gen-iconopt:hover,
.gen-iconopt:focus { border-color: #5aa9cf; }
.gen-iconopt.is-selected { border-color: skyblue; box-shadow: 0 0 0 1px skyblue; }

.gen-panel .button.is-static.gen-host {
    background: var(--gen-page);
    border-color: var(--gen-edge);
    color: var(--gen-dim);
    font-family: var(--bulma-family-code);
    font-size: .8rem;
}

.gen-live {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    background: var(--gen-panel-2);
    border: 1px solid var(--gen-edge);
    border-radius: 10px;
    padding: .12rem .55rem;
    color: var(--gen-dim);
    font-family: inherit;
    font-size: .7rem;
    cursor: pointer;
}
.gen-live:hover { color: #fff; border-color: cadetblue; }
.gen-livedot {
    width: .45rem;
    height: .45rem;
    border-radius: 50%;
    background: var(--gen-dim);
    flex: 0 0 auto;
}
.gen-live.is-on .gen-livedot {
    background: var(--st-ok);
    animation: genpulse 2.4s ease-in-out infinite;
}
@keyframes genpulse {
    0%, 100% { opacity: 1; box-shadow: 0 0 0 0 rgba(63, 191, 95, .5); }
    50%      { opacity: .55; box-shadow: 0 0 0 .22rem rgba(63, 191, 95, 0); }
}
@media (prefers-reduced-motion: reduce) {
    .gen-live.is-on .gen-livedot { animation: none; }
}

/* ---- Schedules and previews ---------------------------------------------- */

a.gen-tab { display: inline-block; }

/* A day is 96 quarter hours across the width, painted where the schedule is active. */
.gen-sched {
    display: grid;
    grid-template-columns: 10rem 1fr 9rem;
    gap: .6rem;
    align-items: center;
    margin-bottom: .3rem;
}
.gen-hours {
    display: grid;
    grid-template-columns: repeat(24, 1fr);
    font-size: .62rem;
    color: var(--gen-dim);
}
.gen-slots {
    display: grid;
    grid-template-columns: repeat(96, 1fr);
    height: 1.5rem;
    border: 1px solid var(--gen-edge);
    border-radius: 3px;
    overflow: hidden;
    user-select: none;
}
.gen-slot { background: var(--gen-panel-2); cursor: pointer; }
.gen-slot:nth-child(4n) { box-shadow: inset -1px 0 0 var(--gen-edge); }
.gen-slot:hover { background: rgba(95, 158, 160, .35); }
.gen-slot.is-on { background: var(--st-ok); }
.gen-schedops { font-size: .72rem; }
.gen-schedops a { margin-right: .5rem; color: var(--gen-dim); }
.gen-schedops a:hover { color: cadetblue; }

.gen-preview {
    width: 100%;
    height: 44rem;
    border: 1px solid var(--gen-edge);
    border-radius: 4px;
    background: #fff;
}

/* ---- Landing page ------------------------------------------------------ */
/* index.php to anyone not signed in. The one page here that sells rather than works, so
   everything is prefixed gen-land and nothing leaks into the application's screens. */

.gen-land { max-width: 76rem; margin: 0 auto; padding-bottom: 3rem; }
.gen-land h1, .gen-land h2, .gen-land h3 {
    font-family: 'AdventPro', var(--bulma-family-primary);
    font-weight: normal;
    color: #fff;
    line-height: 1.08;
}
.gen-land h1 {
    font-size: clamp(2.5rem, 5.4vw, 4.4rem);
    font-variation-settings: 'wght' 720;
    letter-spacing: -.01em;
    margin-bottom: 1.3rem;
}
.gen-land h2 {
    font-size: clamp(1.9rem, 3.6vw, 2.9rem);
    font-variation-settings: 'wght' 680;
    margin-bottom: 1rem;
}
.gen-land h3 { font-size: 1.3rem; font-variation-settings: 'wght' 640; margin-bottom: .5rem; }
.gen-land p { color: #b9c2cf; line-height: 1.65; }
.gen-land strong { color: #fff; }
.gen-land-lead { font-size: 1.18rem; max-width: 38rem; }
.gen-land-accent {
    background: linear-gradient(90deg, #6fd0d6, #00a8f5);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
}
.gen-land-kicker {
    display: inline-flex;
    align-items: center;
    gap: .55rem;
    font-family: var(--bulma-family-code);
    font-size: .74rem;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: cadetblue;
    margin-bottom: 1rem;
}
.gen-land-kicker .gen-livedot { background: var(--st-ok); animation: genpulse 2.4s ease-in-out infinite; }

.gen-land-hero {
    position: relative;
    display: grid;
    grid-template-columns: minmax(0, 1.05fr) minmax(0, .95fr);
    gap: 3rem;
    align-items: center;
    padding-block: 3rem 2.5rem;
}
/* A glow behind the wheel, kept inside the hero so it can never scroll the page sideways. */
.gen-land-hero::before {
    content: '';
    position: absolute;
    right: 0;
    top: 0;
    width: 55%;
    aspect-ratio: 1;
    background: radial-gradient(closest-side, rgba(70, 58, 180, .38), transparent);
    pointer-events: none;
}
.gen-land-hero > div { position: relative; }

.gen-land-cta { display: flex; flex-wrap: wrap; gap: .75rem; margin: 1.9rem 0 1.6rem; }
.gen-land-chips { display: flex; flex-wrap: wrap; gap: .5rem; }
.gen-land-chip {
    font-size: .78rem;
    color: var(--gen-dim);
    border: 1px solid var(--gen-edge);
    border-radius: 999px;
    padding: .25rem .75rem;
    background: rgba(255, 255, 255, .02);
}
.gen-land-chip i { color: cadetblue; margin-right: .4rem; }

.gen-land-wheel { position: relative; max-width: 31rem; margin: 0 auto; }
.gen-land-wheel svg { display: block; width: 100%; height: auto; overflow: visible; }
.gen-land-wheel .gen-wheelmid { width: 25%; }
.gen-land-wheel path { transition: fill .5s; }
.gen-land-seg { transition: transform .6s cubic-bezier(.2, .8, .2, 1); }
.gen-land-legend {
    display: flex;
    justify-content: center;
    flex-wrap: wrap;
    gap: .4rem 1rem;
    font-size: .75rem;
    color: var(--gen-dim);
    margin-top: 1rem;
}
.gen-land-legend span { display: inline-flex; align-items: center; gap: .35rem; }
.gen-land-caption { text-align: center; font-size: .72rem; color: var(--st-unknown); margin-top: .4rem; }

.gen-land-stats {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    background: var(--gen-panel);
    border: 1px solid var(--gen-edge);
    border-radius: 10px;
}
.gen-land-stat { padding: 1.4rem 1.5rem; border-left: 1px solid var(--gen-edge); }
.gen-land-stat:first-child { border-left: 0; }
.gen-land-num {
    font-family: 'AdventPro', var(--bulma-family-primary);
    font-variation-settings: 'wght' 720;
    font-size: 2.7rem;
    line-height: 1;
    color: #fff;
}
.gen-land-stat p { font-size: .85rem; margin-top: .45rem; line-height: 1.45; }

.gen-land-sec { padding-top: 5.5rem; scroll-margin-top: 1rem; }
.gen-land-head { max-width: 48rem; margin-bottom: 2.2rem; }
.gen-land-split {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 3rem;
    align-items: center;
}
.gen-land-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr)); gap: 1rem; }

.gen-land-card {
    background: linear-gradient(180deg, var(--gen-panel), var(--gen-panel-2));
    border: 1px solid var(--gen-edge);
    border-radius: 10px;
    padding: 1.5rem;
    transition: border-color .15s;
}
.gen-land-card:hover { border-color: #34404f; }
.gen-land-card p { font-size: .92rem; }
.gen-land-icon {
    display: grid;
    place-items: center;
    width: 2.6rem;
    height: 2.6rem;
    border-radius: 8px;
    background: rgba(95, 158, 160, .13);
    color: #6fd0d6;
    font-size: 1.1rem;
    margin-bottom: 1rem;
}

.gen-land-ticks li {
    position: relative;
    padding-left: 1.6rem;
    margin-bottom: .75rem;
    color: #b9c2cf;
    line-height: 1.55;
}
.gen-land-ticks li::before {
    content: '';
    position: absolute;
    left: .15rem;
    top: .5rem;
    width: .5rem;
    height: .5rem;
    border-radius: 2px;
    background: cadetblue;
    transform: rotate(45deg);
}

/* ---- Landing: consensus ---- */
.gen-land-vote { display: grid; grid-template-columns: minmax(0, 1.2fr) minmax(0, .8fr); gap: 1rem; }
.gen-land-groups { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: .6rem; }
.gen-land-pg {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: .45rem;
    padding: 1rem .3rem .8rem;
    background: var(--gen-panel-2);
    border: 1px solid var(--gen-edge);
    border-radius: 8px;
    color: var(--gen-ink);
    font-family: inherit;
    font-size: .8rem;
    cursor: pointer;
    transition: border-color .15s, background .15s;
}
.gen-land-pg:hover { border-color: cadetblue; }
.gen-land-pg small { color: var(--gen-dim); font-size: .66rem; }
.gen-land-pg .gen-dot { width: 1rem; height: 1rem; }
.gen-land-pg[aria-pressed="true"] { border-color: var(--st-crit); background: rgba(224, 59, 48, .1); }
.gen-land-verdict dl {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: .3rem 1rem;
    font-size: .85rem;
    margin-bottom: 1.2rem;
}
.gen-land-verdict dt { color: var(--gen-dim); }
.gen-land-verdict dd { font-family: var(--bulma-family-code); color: var(--gen-ink); }
.gen-land-state {
    font-family: 'AdventPro', var(--bulma-family-primary);
    font-weight: normal;
    font-variation-settings: 'wght' 760;
    font-size: 3.4rem;
    line-height: 1.1;
    margin-bottom: .6rem;
}

/* ---- Landing: the message ---- */
.gen-land-msg {
    background: #0b0f15;
    border: 1px solid var(--gen-edge);
    border-radius: 10px;
    overflow: hidden;
    box-shadow: 0 24px 60px rgba(0, 0, 0, .45);
}
.gen-land-msghead {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: .6rem;
    padding: .7rem 1rem;
    background: var(--gen-panel-2);
    border-bottom: 1px solid var(--gen-edge);
    font-size: .82rem;
}
.gen-land-msg pre {
    background: transparent;
    color: #b9c2cf;
    font-family: var(--bulma-family-code);
    font-size: .76rem;
    line-height: 1.75;
    padding: 1rem 1.1rem;
    margin: 0;
    overflow-x: auto;
    white-space: pre;
}
.gen-land-sms {
    border-top: 1px solid var(--gen-edge);
    padding: .7rem 1.1rem;
    font-family: var(--bulma-family-code);
    font-size: .74rem;
    color: var(--gen-dim);
}

/* ---- Landing: pricing ---- */
.gen-land-fields {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: .2rem 1rem;
    margin: 1rem 0 .6rem;
}
.gen-land-range { width: 100%; accent-color: cadetblue; margin-top: .6rem; }
.gen-land-out { margin-top: 1.2rem; padding-top: 1rem; border-top: 1px solid var(--gen-edge); }
.gen-land-total {
    font-family: 'AdventPro', var(--bulma-family-primary);
    font-variation-settings: 'wght' 720;
    font-size: 3.2rem;
    line-height: 1.1;
    color: #fff;
}

/* ---- Landing: comparison and close ---- */
.gen-land-compare { border: 1px solid var(--gen-edge); border-radius: 10px; overflow: hidden; }
.gen-land-row { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
.gen-land-row > div { padding: .9rem 1.2rem; border-top: 1px solid var(--gen-edge); color: var(--gen-dim); }
.gen-land-row > div + div {
    border-left: 1px solid var(--gen-edge);
    background: rgba(95, 158, 160, .05);
    color: var(--gen-ink);
}
.gen-land-row i { width: 1.1rem; margin-right: .45rem; }
.gen-land-row.is-head > div {
    border-top: 0;
    background: var(--gen-panel-2);
    font-size: .72rem;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--gen-dim);
}

.gen-land-final {
    margin-top: 5.5rem;
    padding: 3.5rem 2rem;
    text-align: center;
    border: 1px solid #2c2a5c;
    border-radius: 14px;
    background: radial-gradient(ellipse at top, rgba(80, 70, 190, .35), transparent 70%), var(--gen-gradient);
}
.gen-land-final p { max-width: 36rem; margin: 0 auto; }
.gen-land-final .gen-land-cta { justify-content: center; margin-bottom: 0; }

@media (max-width: 1023px) {
    .gen-land-hero, .gen-land-split, .gen-land-vote { grid-template-columns: minmax(0, 1fr); }
    .gen-land-hero { gap: 2rem; padding-top: 1.5rem; }
    .gen-land-hero::before { width: 90%; top: auto; bottom: 0; }
    .gen-land-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .gen-land-stat:nth-child(3) { border-left: 0; }
    .gen-land-stat:nth-child(n+3) { border-top: 1px solid var(--gen-edge); }
}
@media (max-width: 600px) {
    .gen-land-stats, .gen-land-fields, .gen-land-row { grid-template-columns: minmax(0, 1fr); }
    .gen-land-stat, .gen-land-stat:nth-child(3) { border-left: 0; border-top: 1px solid var(--gen-edge); }
    .gen-land-stat:first-child { border-top: 0; }
    .gen-land-row > div + div { border-left: 0; border-top: 0; }
    .gen-land-groups { grid-template-columns: repeat(3, minmax(0, 1fr)); }
    .gen-land-sec { padding-top: 4rem; }
    .gen-land-msg pre { font-size: .62rem; padding-inline: .7rem; }
}
@media (prefers-reduced-motion: reduce) {
    .gen-land-seg, .gen-land-wheel path { transition: none; }
    .gen-land-kicker .gen-livedot { animation: none; }
}

/* ---- Comparison page ------------------------------------------------- */
/* comparison.php, built on the landing classes above. */

.gen-land-hero.is-single { grid-template-columns: minmax(0, 1fr); padding-bottom: 2rem; }
.gen-land-hero.is-single::before { width: 40%; }
.gen-land-hero.is-single .gen-land-lead { max-width: 52rem; }

/* The two architecture diagrams. Colours come from the tokens so they follow the theme. */
.gen-arch .gen-land-card.is-ours { border-color: #2c5a60; background: linear-gradient(180deg, #11262c, var(--gen-panel-2)); }
.gen-arch-tag {
    font-family: var(--bulma-family-code);
    font-size: .7rem;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--gen-dim);
    margin-bottom: .8rem;
}
.is-ours .gen-arch-tag { color: #6fd0d6; }
.gen-arch svg { display: block; width: 100%; height: auto; }
.gen-arch svg rect { fill: var(--gen-panel-2); stroke: #34404f; stroke-width: 1.2; }
.gen-arch svg rect.us { stroke: cadetblue; stroke-width: 1.6; }
.gen-arch svg rect.bad { stroke: var(--st-crit); stroke-width: 1.6; }
.gen-arch svg .ln { fill: none; stroke: #34404f; stroke-width: 1.6; }
.gen-arch svg .ln.us { stroke: cadetblue; }
.gen-arch svg text { fill: var(--gen-ink); font-size: 13px; text-anchor: middle; font-family: var(--bulma-family-primary); }
.gen-arch svg text.note { fill: var(--gen-dim); font-size: 11.5px; }
.gen-arch svg circle.ok { fill: var(--st-ok); }
.gen-arch svg circle.dead { fill: var(--st-unknown); }

/* The cascade, five steps that read left to right, top to bottom on a phone. */
.gen-cascade { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 1rem; list-style: none; margin: 0; }
.gen-cascade li {
    position: relative;
    background: linear-gradient(180deg, var(--gen-panel), var(--gen-panel-2));
    border: 1px solid var(--gen-edge);
    border-radius: 10px;
    padding: 1.3rem 1.2rem;
}
.gen-cascade li + li::before {
    content: '';
    position: absolute;
    left: -.85rem;
    top: 1.9rem;
    border: .4rem solid transparent;
    border-left-color: cadetblue;
}
.gen-cascade-n {
    display: inline-grid;
    place-items: center;
    width: 1.8rem;
    height: 1.8rem;
    border-radius: 50%;
    background: rgba(95, 158, 160, .15);
    color: #6fd0d6;
    font-family: var(--bulma-family-code);
    font-size: .8rem;
    margin-bottom: .7rem;
}
.gen-cascade h3 { font-size: 1.15rem; }
.gen-cascade p { font-size: .86rem; }
.gen-land-cols { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 2rem; }

/* Channels */
.gen-chan { display: grid; grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr)); gap: .8rem; }
.gen-land-grid.is-five { grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr)); }
.gen-chan-item {
    display: flex;
    gap: .9rem;
    align-items: flex-start;
    background: var(--gen-panel);
    border: 1px solid var(--gen-edge);
    border-radius: 10px;
    padding: 1rem 1.1rem;
}
.gen-chan-item i { color: #6fd0d6; font-size: 1.2rem; margin-top: .15rem; width: 1.4rem; text-align: center; }
.gen-chan-item strong { display: block; margin-bottom: .15rem; }
.gen-chan-item span { color: var(--gen-dim); font-size: .84rem; line-height: 1.45; }

/* The feature table */
.gen-land-scroll {
    overflow-x: auto;
    border: 1px solid var(--gen-edge);
    border-radius: 10px;
}
table.gen-land-matrix { width: 100%; min-width: 64rem; border-collapse: collapse; font-size: .8rem; }
.gen-land-matrix th,
.gen-land-matrix td {
    padding: .8rem .9rem;
    border-top: 1px solid var(--gen-edge);
    border-left: 1px solid var(--gen-edge);
    vertical-align: top;
    text-align: left;
    line-height: 1.45;
    color: var(--gen-dim);
}
.gen-land-matrix thead th {
    border-top: 0;
    background: var(--gen-panel-2);
    font-size: .72rem;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--gen-ink);
    white-space: nowrap;
}
/* The feature names stay in view while the table scrolls sideways. */
.gen-land-matrix th:first-child {
    position: sticky;
    left: 0;
    z-index: 1;
    width: 14rem;
    border-left: 0;
    background: var(--gen-panel);
    color: var(--gen-ink);
    font-weight: 600;
}
.gen-land-matrix thead th.is-us { width: 13rem; }
.gen-land-matrix .is-us { background: rgba(95, 158, 160, .08); color: var(--gen-ink); }
.gen-land-matrix thead th.is-us { background: #16303a; color: #6fd0d6; }
.gen-land-matrix tr.is-sec th {
    width: auto;
    background: var(--gen-panel-2);
    font-family: var(--bulma-family-code);
    font-size: .7rem;
    font-weight: normal;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: cadetblue;
}
.gen-land-mark { display: block; font-weight: 600; color: var(--gen-ink); margin-bottom: .2rem; white-space: nowrap; }
.gen-land-mark i, .gen-land-legend i { width: 1rem; margin-right: .3rem; }
.gen-land-swipe { display: none !important; }

.gen-land-src { border-top: 1px solid var(--gen-edge); padding: .6rem 0; }
.gen-land-src summary { cursor: pointer; color: var(--gen-dim); font-size: .85rem; }
.gen-land-src ul { margin: .6rem 0 0 1.2rem; }
.gen-land-src li { font-size: .78rem; margin-bottom: .3rem; overflow-wrap: anywhere; }

@media (max-width: 1023px) {
    .gen-land-swipe { display: inline-flex !important; }
    .gen-cascade { grid-template-columns: minmax(0, 1fr); }
    .gen-cascade li + li::before { left: 1.9rem; top: -.85rem; border-left-color: transparent; border-top-color: cadetblue; }
}
@media (max-width: 600px) {
    .gen-land-matrix th:first-child { width: 9rem; }
    .gen-land-cols { grid-template-columns: minmax(0, 1fr); }
}
