/* The plain building blocks the ported pages name besides their own: rows and stacks, quiet
   and small words, a search field, a dropdown, the turning ring, a dialog over the page and its
   scrim, the messages in the corner, notices and tags, a picture's box, the cards of what comes
   later. Colours and measures are the theme's (tokens.css); hub.css gives them our look. */

button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }
button:disabled { cursor: default; }
.stack { display: flex; flex-direction: column; gap: 14px; }
.row.wrap { flex-wrap: wrap; }
.grow { flex: 1; min-width: 0; }
.muted { color: var(--hub-text-dim); }
.small { font-size: 12px; }
.bad { color: var(--hub-danger); }
.ok { color: var(--hub-ok); }
.warn { color: var(--hub-warn); }
.selectable { user-select: text; }
.hub .hub-stage, .hub .hub-stage * { user-select: none; }
.hub .selectable, .hub .selectable *, .hub input, .hub textarea { user-select: text; }

/* a search field: its magnifier inside on the left */
.search { position: relative; display: flex; }
.search .input { width: 100%; }
.search svg { position: absolute; top: 50%; transform: translateY(-50%); pointer-events: none; }
input[type=search]::-webkit-search-cancel-button { filter: grayscale(1); }

/* a dropdown: the browser's own, with a chevron of ours (grey: it reads on both looks) */
.select {
  appearance: none; -webkit-appearance: none; cursor: pointer; font: inherit; min-width: 0;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5l5 5 5-5' fill='none' stroke='%23959db0' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-size: 10px 7px; background-repeat: no-repeat; background-position: right 12px center;
}
.input { font: inherit; min-width: 0; }

/* the turning ring */
.spinner { display: inline-block; width: 18px; height: 18px; border-radius: 50%; border: 2px solid var(--hub-rail); border-top-color: var(--hub-accent); animation: hub-spin 0.8s linear infinite; vertical-align: middle; flex: none; }
@keyframes hub-spin { to { transform: rotate(360deg); } }

/* a dialog over the page */
.overlay { position: fixed; inset: 0; display: flex; align-items: center; justify-content: center; padding: 28px; background: var(--hub-scrim); z-index: 50; }
.dialog { width: min(560px, 100%); max-height: 100%; display: flex; flex-direction: column; overflow: hidden; }
.dialog-head { display: flex; align-items: center; gap: 10px; }
.dialog-head h2 { display: flex; align-items: center; gap: 8px; margin: 0; }
.dialog-body { overflow: auto; min-height: 0; }
.dialog-foot { display: flex; justify-content: flex-end; align-items: center; }
.log { white-space: pre-wrap; overflow: auto; max-height: 36vh; padding: 10px 12px; margin: 8px 0 0; font: 11px/1.45 ui-monospace, Consolas, monospace; }

/* the messages in the corner */
.toasts { position: fixed; display: flex; flex-direction: column; gap: 8px; align-items: flex-end; pointer-events: none; right: 20px; bottom: 20px; z-index: 60; }
.toast { display: flex; gap: 10px; align-items: flex-start; max-width: 420px; padding: 10px 14px; pointer-events: auto; font-size: 12px; animation: hub-toast 0.18s ease-out; }
.toast.ok svg { color: var(--hub-ok); }
.toast.error svg { color: var(--hub-danger); }
.toast svg { flex: none; }
@keyframes hub-toast { from { transform: translateY(8px); opacity: 0; } }

/* notices, tags, an empty list */
.notice { display: flex; gap: 10px; align-items: flex-start; padding: 10px 12px; }
.tag { display: inline-flex; align-items: center; gap: 4px; height: 22px; padding: 0 8px; white-space: nowrap; }
.empty { padding: 32px 16px; text-align: center; color: var(--hub-text-dim); }
.empty b { display: block; margin-bottom: 4px; }

/* a picture filling its box */
.pic { background-size: cover; background-position: center; width: 100%; height: 100%; border-radius: inherit; }

/* the shell's frame: the stage under the bar fills the window */
.hub body { overflow: hidden; }
.hub #app { height: 100%; }
.hub .splash { height: 100%; display: grid; place-items: center; gap: 12px; text-align: center; }
.hub .splash.resting p { max-width: 460px; color: var(--hub-text-dim); }

/* the route map (hub/routemap.js) */
.routemap { position: relative; width: 100%; overflow: hidden; touch-action: none; cursor: grab; }
.routemap canvas { width: 100%; height: 100%; display: block; }
.routemap .state { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; gap: 10px; pointer-events: none; }
.routemap .legend { position: absolute; left: 10px; bottom: 8px; font-size: 11.5px; padding: 3px 8px; border-radius: 4px; pointer-events: none; }

/* a part that comes later (hub/later.js) */
.hub-later { display: flex; flex-direction: column; align-items: center; text-align: center; gap: 8px; padding: 48px 24px; color: var(--hub-text-soft); }
.hub-later .badge { width: 52px; height: 52px; display: grid; place-items: center; border-radius: 50%; background: rgba(var(--hub-accent-rgb), 0.14); color: var(--hub-accent-text); }
.hub-later b { font-size: 15px; color: var(--hub-text); }
.hub-later p { margin: 0; max-width: 420px; color: var(--hub-text-dim); }

/* the old saves' offer over the start (app.js) */
.hub-migrate { position: fixed; left: 24px; bottom: 24px; width: min(420px, calc(100% - 48px)); z-index: 45; }

/* Settings (pages/settings.js) */
.hub-addon .hub-path, .hub-game-settings .hub-path { display: inline-block; min-height: 22px; line-height: 22px; overflow-wrap: anywhere; }
.hub-settings { display: flex; flex-direction: column; gap: 18px; }
.hub-settings .settings-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 22px; }
.hub-settings .settings-col { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.hub-settings .setting-row { display: grid; align-items: center; }
.hub-settings .setting-row > .hub-switch, .hub-settings .setting-row > .hub-slider { width: 100%; }
.hub-settings .hub-caps { margin: 0 0 6px; }

/* the service record's pieces: plain layout helpers (the theme's tokens give them their look) */
.grid-2 { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px 16px; }
.ellipsis { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.num { font-variant-numeric: tabular-nums; }
.avatar { width: 34px; height: 34px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; font-weight: 700; flex: none; }
.stats { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 12px; }
.stat { padding: 14px 16px; }
.stat b { display: block; font-size: 22px; font-weight: 700; font-variant-numeric: tabular-nums; letter-spacing: -0.01em; }
.stat span { color: var(--hub-text-dim); font-size: 12.5px; }
.progress { height: 6px; border-radius: 3px; overflow: hidden; }
.progress > div { height: 100%; background: var(--hub-accent); transition: width 0.2s; }
.table { width: 100%; border-collapse: collapse; }
.table th { text-align: left; padding: 8px 10px; white-space: nowrap; }
.table td { padding: 9px 10px; vertical-align: middle; }
.line-badge { display: inline-flex; align-items: center; justify-content: center; min-width: 34px; height: 24px; padding: 0 7px; font-variant-numeric: tabular-nums; }
/* (a labelled field on a page in the sheet: the label above) */
.hub-page-body .field { display: flex; flex-direction: column; gap: 6px; min-width: 0; }

/* The schedule-bar switch (the brand guide; Schedulo TXC's `widgets::switch`): the symbol's
   tick (3 px) and stub (6 px), then a 58 x 26 bar with a round segment that slides across like a
   schedule block. Off: a light blue bar, a navy segment. On: a navy bar with a Bright Blue edge,
   an Electric Blue segment with a check in it (the look's switch: a sun, then a moon). The same
   colours in the light and the dark look. */
.sch-bar { --sch-edge: #3f7bff; display: inline-flex; align-items: center; flex: none; height: 32px; }
.sch-bar .tick { position: relative; width: 9px; height: 32px; flex: none; }
.sch-bar .tick::before { content: ""; position: absolute; left: 0; top: 0; width: 3px; height: 32px; border-radius: 1.5px; background: #3f7bff; }
.sch-bar .tick::after { content: ""; position: absolute; left: 3px; width: 7px; top: 14.5px; height: 3px; background: #3f7bff; }
.sch-bar .pill { position: relative; width: 58px; height: 26px; flex: none; box-sizing: border-box; border-radius: 13px; background: #4c8df0; border: 1.5px solid #4c8df0; transition: background 0.2s, border-color 0.2s; }
.sch-bar .seg { position: absolute; top: -1.5px; left: -1.5px; width: 26px; height: 26px; box-sizing: border-box; border-radius: 50%; background: #071433; border: 1.5px solid var(--sch-edge); color: #eef2ff; display: grid; place-items: center; transition: transform 0.2s cubic-bezier(0.3, 0.7, 0.4, 1), background 0.2s; }
.sch-bar .seg svg { grid-area: 1 / 1; width: 15px; height: 15px; transition: opacity 0.18s, transform 0.2s; }
.sch-bar .when-on { opacity: 0; transform: scale(0.6); }
.sch-bar.on .pill { background: #162c66; border-color: var(--sch-edge); }
.sch-bar.on .seg { transform: translateX(32px); background: #1e4bff; }
.sch-bar.on .when-on { opacity: 1; transform: none; }
.sch-bar.on .when-off { opacity: 0; transform: rotate(60deg) scale(0.6); }
:hover > .sch-bar, :focus-visible > .sch-bar, input:focus-visible + .sch-bar { --sch-edge: #7fa5ff; }
:disabled > .sch-bar, input:disabled + .sch-bar { opacity: 0.45; }
/* the compact switch (Schedulo TXC's compact `Switch`) for dense panels and lists: a 2 px tick,
   a 4 px stub and a 36 x 18 bar; off, a white segment on a soft bar; on, as the full size */
.sch-bar.compact { height: 22px; }
.sch-bar.compact .tick { width: 6px; height: 22px; }
.sch-bar.compact .tick::before { width: 2px; height: 22px; border-radius: 1px; }
.sch-bar.compact .tick::after { left: 2px; width: 5px; top: 10px; height: 2px; }
.sch-bar.compact .pill { width: 36px; height: 18px; border-radius: 9px; background: var(--hub-field); border-color: var(--hub-edge); }
.sch-bar.compact .seg { top: -0.5px; left: -0.5px; width: 16px; height: 16px; background: #ffffff; border-color: var(--hub-edge); color: #ffffff; }
.sch-bar.compact .seg svg { width: 11px; height: 11px; }
.sch-bar.compact.on .pill { background: #162c66; border-color: var(--sch-edge); }
.sch-bar.compact.on .seg { transform: translateX(18px); background: #1e4bff; border-color: var(--sch-edge); }
:hover > .sch-bar.compact:not(.on) .pill, :hover > .sch-bar.compact:not(.on) .seg { border-color: #7fa5ff; }
@media (prefers-reduced-motion: reduce) { .sch-bar .pill, .sch-bar .seg, .sch-bar .seg svg { transition: none; } }
/* the checkbox under a switch: still there for the keyboard and screen readers, not seen */
.sch-toggle input, .hub-switch input, .co-switch input { position: absolute; width: 1px; height: 1px; margin: 0; opacity: 0; pointer-events: none; }
.sch-toggle { position: relative; display: inline-flex; align-items: center; gap: 10px; cursor: pointer; }
.hub-switch { position: relative; display: flex; align-items: center; gap: 10px; cursor: pointer; }
.hub-switch > span:not(.sch-bar) { flex: 1; min-width: 0; }
