/* ==========================================================================
   AirOps — public app (login, admin, dashboard)
   --------------------------------------------------------------------------
   Visual layer is shared with AirHub (https://airhub.hotairapp.com).
   The --hub-* token namespace is extracted from AirHub's production CSS and
   re-used verbatim. See server/airops/UI_STYLE_GUIDE.md for the full guide.
   ========================================================================== */

/* ---- Theme tokens (light = default) --------------------------------------
 * Light is the unconditional default to match AirHub. `color-scheme: light`
 * is pinned on :root so OS-level form controls and scrollbars stay light
 * even when the user's OS is set to dark mode. Dark variants only apply
 * when explicitly opted-in via html[data-theme="dark"].
 * -------------------------------------------------------------------------- */
:root,
html[data-theme="light"] {
  color-scheme: light;
  --hub-bg:               #e8f4f8;
  --hub-surface:          #ffffff;
  --hub-surface-elevated: #ffffff;
  --hub-surface-muted:    #f4fafc;
  --hub-surface-hover:    #eef6f9;
  --hub-border:           #d0dee8;
  --hub-border-strong:    #9fc4d4;
  --hub-text:             #1a1a1a;
  --hub-text-secondary:   #3d5a68;
  --hub-text-muted:       #5c6b7a;
  --hub-accent:           #5bb4e5;
  --hub-accent-hover:     #49a8dc;
  --hub-accent-soft:      #5bb4e52e;
  --hub-eyebrow:          #f97316;
  --hub-shadow:           0 1px 3px #1e3a4714;
  --hub-card-shadow:      0 1px 4px #1e3a471a;
  --hub-danger:           #d64545;
  --hub-danger-soft:      #d6454514;
  --hub-warn:             #d29922;
  --hub-warn-soft:        #fff8e6;
  --hub-success:          #1a7f37;
  --hub-success-soft:     #e8f5ec;
  --hub-input-bg:         #ffffff;
  --hub-input-border:     #c5d4de;
  --hub-btn-primary:      #f97316;
  --hub-btn-primary-hover:#ea580c;
  --hub-btn-secondary-bg: #ffffff;
  --hub-btn-secondary-hover-bg: #eef6f9;
  --hub-focus:            #5bb4e5;
  --hub-focus-ring:       #5bb4e540;

  /* Aliases for legacy AirOps references (any leftover var(--bg) / var(--text) /
     var(--accent) etc. resolves to the matching hub token). */
  --bg:           var(--hub-bg);
  --panel:        var(--hub-surface);
  --panel-alt:    var(--hub-surface-muted);
  --border:       var(--hub-border);
  --text:         var(--hub-text);
  --muted:        var(--hub-text-muted);
  --accent:       var(--hub-accent);
  --accent-strong:#2e7adf;
  --danger:       var(--hub-danger);
  --good:         var(--hub-success);
  --warn:         var(--hub-warn);
  --shadow:       var(--hub-card-shadow);

  /* Layout */
  --radius:       12px;
  --radius-sm:    8px;
  --radius-pill:  999px;

  --font-sans: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue",
               Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji";
  --font-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono",
               "Courier New", monospace;
}

html[data-theme="dark"] {
  color-scheme: dark;
  --hub-bg:               #0d1117;
  --hub-surface:          #161b22;
  --hub-surface-elevated: #21262d;
  --hub-surface-muted:    #0d1117;
  --hub-surface-hover:    #1c2128;
  --hub-border:           #30363d;
  --hub-border-strong:    #484f58;
  --hub-text:             #e6edf3;
  --hub-text-secondary:   #c9d1d9;
  --hub-text-muted:       #8b949e;
  --hub-accent:           #58a6ff;
  --hub-accent-hover:     #79c0ff;
  --hub-accent-soft:      #58a6ff24;
  --hub-eyebrow:          #f78166;
  --hub-shadow:           none;
  --hub-card-shadow:      none;
  --hub-danger:           #f85149;
  --hub-danger-soft:      #f8514922;
  --hub-warn:             #d29922;
  --hub-warn-soft:        #2d2206;
  --hub-success:          #3fb950;
  --hub-success-soft:     #1f3026;
  --hub-input-bg:         #0d1117;
  --hub-input-border:     #30363d;
  --hub-btn-primary:      #f97316;
  --hub-btn-primary-hover:#ea580c;
  --hub-btn-secondary-bg: #21262d;
  --hub-btn-secondary-hover-bg: #1c2128;
  --hub-focus:            #58a6ff;
  --hub-focus-ring:       #58a6ff33;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  height: 100%;
  background: var(--hub-bg);
  color: var(--hub-text);
  font-family: var(--font-sans);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

a { color: var(--hub-accent); text-decoration: none; transition: color .12s ease; }
a:hover { color: var(--hub-accent-hover); text-decoration: underline; }

input, select, textarea, button {
  font-family: inherit;
  font-size: 0.95rem;
}

/* ============================== Layout ============================== */
.container { max-width: 1100px; margin: 0 auto; padding: 1.5rem; }

/* ============================== Topbar ============================== */
.topbar {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 0.7rem 1.25rem;
  background: var(--hub-surface);
  border-bottom: 1px solid var(--hub-border);
  box-shadow: var(--hub-shadow);
}
.topbar .brand {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  font-weight: 700;
  font-size: 1.05rem;
  letter-spacing: -0.01em;
  color: var(--hub-text);
  text-decoration: none;
}
.topbar .brand .brand-mark {
  height: 28px;
  width: auto;
  object-fit: contain;
  flex-shrink: 0;
}
.topbar .brand .brand-divider {
  color: var(--hub-text-muted);
  font-weight: 500;
  margin: 0 1px;
}
.topbar .brand .brand-product {
  color: var(--hub-text);
  font-weight: 700;
}
/* Legacy dot fallback (kept so any old markup stays usable). */
.topbar .brand .dot {
  display: inline-block;
  width: 0.55rem;
  height: 0.55rem;
  border-radius: 50%;
  background: var(--hub-accent);
  margin-right: 0.45rem;
  vertical-align: middle;
}
.topbar .spacer { flex: 1; }
.topbar .muted { color: var(--hub-text-muted); font-size: 0.9rem; }

/* ============================== Cards ============================== */
.card {
  background: var(--hub-surface);
  border: 1px solid var(--hub-border);
  border-radius: var(--radius);
  padding: 1.15rem 1.2rem;
  box-shadow: var(--hub-card-shadow);
}
.card + .card { margin-top: 1rem; }

/* ============================== Buttons ============================== */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
  background: var(--hub-btn-primary);
  color: #ffffff;
  border: 1px solid transparent;
  padding: 0.55rem 0.95rem;
  border-radius: var(--radius-sm);
  font-weight: 600;
  cursor: pointer;
  text-decoration: none;
  transition: background-color .15s ease, border-color .15s ease,
              color .15s ease, transform .12s ease, box-shadow .15s ease;
  box-shadow: 0 1px 0 rgba(0,0,0,0.06), 0 4px 12px rgba(249,115,22,0.18);
}
.btn:hover {
  background: var(--hub-btn-primary-hover);
  color: #ffffff;
  text-decoration: none;
  transform: translateY(-1px);
}
.btn:active { transform: translateY(0); }
.btn:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px var(--hub-focus-ring);
}
.btn.ghost {
  background: var(--hub-btn-secondary-bg);
  color: var(--hub-text);
  border: 1px solid var(--hub-border);
  box-shadow: none;
}
.btn.ghost:hover {
  background: var(--hub-btn-secondary-hover-bg);
  border-color: var(--hub-border-strong);
  color: var(--hub-text);
}
.btn.danger {
  background: var(--hub-danger);
  color: #ffffff;
  box-shadow: 0 1px 0 rgba(0,0,0,0.06), 0 4px 12px rgba(214, 69, 69, 0.18);
}
.btn.danger:hover { background: #b13434; color: #ffffff; }

/* ============================== Forms ============================== */
label {
  display: block;
  margin-bottom: 0.3rem;
  color: var(--hub-text-secondary);
  font-size: 0.85rem;
  font-weight: 500;
}
input[type="text"], input[type="email"], input[type="password"],
input[type="number"], input[type="datetime-local"], textarea, select {
  width: 100%;
  padding: 0.55rem 0.7rem;
  background: var(--hub-input-bg);
  border: 1px solid var(--hub-input-border);
  border-radius: var(--radius-sm);
  color: var(--hub-text);
  transition: border-color .12s ease, box-shadow .12s ease;
}
input:focus, textarea:focus, select:focus {
  outline: none;
  border-color: var(--hub-focus);
  box-shadow: 0 0 0 3px var(--hub-focus-ring);
}

.form-row { margin-bottom: 0.85rem; }
.form-row.inline { display: flex; gap: 0.75rem; align-items: end; }
.form-row.inline > * { flex: 1; }

/* ============================== Notice ============================== */
.notice {
  padding: 0.65rem 0.85rem;
  border-radius: var(--radius-sm);
  margin-bottom: 0.85rem;
  background: var(--hub-danger-soft);
  color: var(--hub-danger);
  border: 1px solid rgba(214, 69, 69, 0.30);
  display: none;
  font-size: 0.92rem;
}
.notice.ok {
  background: var(--hub-success-soft);
  color: var(--hub-success);
  border-color: rgba(26, 127, 55, 0.30);
}

/* ============================== Tables ============================== */
table { width: 100%; border-collapse: collapse; }
table th, table td {
  text-align: left;
  padding: 0.6rem 0.6rem;
  border-bottom: 1px solid var(--hub-border);
  font-size: 0.92rem;
  color: var(--hub-text);
}
table th {
  color: var(--hub-text-muted);
  font-weight: 600;
  font-size: 0.78rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
table tbody tr:hover {
  background: var(--hub-surface-hover);
}

/* ============================== Badge ============================== */
.badge {
  display: inline-block;
  padding: 0.1rem 0.55rem;
  border-radius: var(--radius-pill);
  background: var(--hub-accent-soft);
  color: var(--hub-accent);
  font-size: 0.74rem;
  font-weight: 600;
  border: 1px solid var(--hub-accent-soft);
}

/* ============================== Dashboard layout ============================== */
.dash {
  position: fixed;
  inset: 0;
  display: grid;
  grid-template-columns: 1fr 360px;
  grid-template-rows: 60px 1fr;
}
.dash header {
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 0 1.1rem;
  border-bottom: 1px solid var(--hub-border);
  background: var(--hub-surface);
  box-shadow: var(--hub-shadow);
  backdrop-filter: blur(6px);
}
.dash header .brand {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  color: var(--hub-text);
  text-decoration: none;
  font-weight: 700;
}
.dash header .brand-mark { height: 26px; width: auto; object-fit: contain; }
.dash header .brand-divider { color: var(--hub-text-muted); font-weight: 500; margin: 0 1px; }
.dash header .title { font-weight: 700; color: var(--hub-text); }
.dash header .stats { display: flex; gap: 1.1rem; }
.dash header .stat { display: flex; gap: 0.35rem; align-items: baseline; }
.dash header .stat .n { font-size: 1.1rem; font-weight: 700; color: var(--hub-text); }
.dash header .stat .l { color: var(--hub-text-muted); font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.06em; }
.dash header .spacer { flex: 1; }
.dash header .muted { color: var(--hub-text-muted); font-family: var(--font-mono); font-size: 0.85rem; }

.dash main { position: relative; }
#map { position: absolute; inset: 0; }

.dash aside {
  background: var(--hub-surface);
  border-left: 1px solid var(--hub-border);
  overflow-y: auto;
  padding: 1rem;
}

.feed-indicator {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.85rem;
  font-weight: 500;
  padding: 0.25rem 0.65rem;
  border-radius: var(--radius-pill);
  border: 1px solid var(--hub-border);
  background: var(--hub-surface);
  color: var(--hub-text-secondary);
}
.feed-indicator .pulse {
  width: 0.55rem;
  height: 0.55rem;
  border-radius: 50%;
  background: var(--hub-text-muted);
}
.feed-indicator.ok    { color: var(--hub-success); border-color: rgba(26,127,55,0.30); background: var(--hub-success-soft); }
.feed-indicator.ok    .pulse { background: var(--hub-success); }
.feed-indicator.warn  { color: var(--hub-warn); border-color: rgba(210, 153, 34, 0.30); background: var(--hub-warn-soft); }
.feed-indicator.warn  .pulse { background: var(--hub-warn); }
.feed-indicator.bad   { color: var(--hub-danger); border-color: rgba(214, 69, 69, 0.30); background: var(--hub-danger-soft); }
.feed-indicator.bad   .pulse { background: var(--hub-danger); }

/* ============================== METAR card ==============================
 * Compact, single-column block. The raw observation wraps so long reports
 * don't push out of the right rail; the key/value table aligns labels in a
 * narrow first column and lets values flow.
 * -------------------------------------------------------------------------- */
#metarCard .metar-head {
  font-size: 0.78rem;
  color: var(--hub-text-muted);
  letter-spacing: 0.02em;
  margin-bottom: 0.35rem;
}
#metarCard .metar-head-sep { margin: 0 0.4em; opacity: 0.6; }
#metarCard .metar-raw {
  font-family: var(--font-mono);
  font-size: 0.78rem;
  line-height: 1.35;
  color: var(--hub-text-secondary);
  background: var(--hub-surface-muted);
  border: 1px solid var(--hub-border);
  border-radius: var(--radius-sm);
  padding: 0.45rem 0.55rem;
  margin-bottom: 0.55rem;
  word-break: break-word;
  white-space: pre-wrap;
}
#metarCard .metar-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.85rem;
  table-layout: fixed;
}
#metarCard .metar-table td {
  padding: 0.25rem 0.35rem;
  border-bottom: none;
  color: var(--hub-text);
  font-size: 0.85rem;
  vertical-align: top;
  text-transform: none;
  letter-spacing: 0;
  word-break: break-word;
}
#metarCard .metar-table td:first-child {
  color: var(--hub-text-muted);
  width: 38%;
  font-weight: 500;
}
#metarCard .metar-stale {
  margin-top: 0.5rem;
  color: var(--hub-warn);
  font-size: 0.78rem;
}

/* ============================== Wind sounding card ======================
 * The wind card is intentionally a dark island inside the light dashboard
 * chrome — it mirrors the Flutter app's winds tab so pilots see the same
 * visual language across mobile + web. See lib/external/wind_panel_tabular_view.dart
 * for the source spec.
 * Container: black surface, rounded, 3-column grid (Alt / Dir / Speed).
 * The "Derived from balloon drift" caption sits ABOVE the dark island so
 * the island itself stays clean.
 * -------------------------------------------------------------------------- */
.wind-card-block { margin-top: 1rem; }
.wind-card-block + .card { margin-top: 1rem; }
.wind-card-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.6rem;
  padding: 0 0.25rem 0.4rem;
}
.wind-card-title {
  margin: 0;
  font-size: 0.95rem;
  font-weight: 700;
  color: var(--hub-text);
  letter-spacing: -0.01em;
}
.wind-card-caption {
  margin: 0;
  font-size: 0.78rem;
  color: var(--hub-text-muted);
  letter-spacing: 0.01em;
}

.wind-card {
  background: rgba(0, 0, 0, 0.90);
  border-radius: 12px;
  overflow: hidden;
  color: #fff;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.18);
  display: flex;
  flex-direction: column;
}
.wind-col-header,
.wind-row {
  display: grid;
  grid-template-columns: 64px 1fr 56px;
  align-items: center;
  column-gap: 6px;
  padding: 5px 8px;
}
.wind-col-header {
  border-bottom: 1px solid rgba(255, 255, 255, 0.12);
  padding-top: 6px;
  padding-bottom: 4px;
}
.wind-col {
  font-size: 12px;
  font-weight: 600;
  color: rgba(255, 255, 255, 0.55);
  letter-spacing: 0.02em;
  line-height: 1.1;
  text-align: center;
}
.wind-col-alt { text-align: center; }
.wind-col-dir { text-align: center; display: flex; align-items: center; justify-content: center; gap: 4px; }
.wind-col-spd { text-align: center; }

.wind-rows {
  max-height: 260px;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}
.wind-rows::-webkit-scrollbar { width: 6px; }
.wind-rows::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.12); border-radius: 3px; }

.wind-row { position: relative; }
.wind-row .wind-col-alt {
  color: #FF9800;
  font-size: 16px;
  font-weight: 600;
  letter-spacing: 0;
  font-variant-numeric: tabular-nums;
}
.wind-row .wind-col-dir {
  color: rgba(255, 255, 255, 0.90);
  font-size: 14px;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
}
.wind-row .wind-col-spd {
  color: #fff;
  font-size: 16px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.wind-row .wind-spd-val { display: inline-block; }
.wind-arrow {
  display: inline-block;
  color: #90AEE5;
  font-size: 14px;
  line-height: 1;
  transform-origin: center;
  width: 1em;
  text-align: center;
}
.wind-dir-text {
  display: inline-block;
  min-width: 3em;
  text-align: left;
}

.wind-row-hi {
  background: rgba(21, 101, 192, 0.58);
  border-left: 3px solid #4DD0E1;
  padding-left: 5px;
}
.wind-row-hi .wind-col-alt { color: #FFB74D; }

.wind-empty {
  padding: 14px 12px;
  color: rgba(255, 255, 255, 0.55);
  font-size: 12px;
  text-align: center;
}

.wind-footer {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
  background: rgba(255, 255, 255, 0.05);
  color: rgba(255, 255, 255, 0.55);
  font-size: 11px;
  letter-spacing: 0.02em;
  padding: 5px 8px;
}
.wind-footer-sep { color: rgba(255, 255, 255, 0.24); }

@media (min-width: 801px) {
  .wind-col-header,
  .wind-row { padding: 6px 10px; }
  .wind-row .wind-col-alt { font-size: 16px; }
  .wind-row .wind-col-spd { font-size: 16px; }
  .wind-col { font-size: 12px; }
  .wind-footer { font-size: 12px; padding: 6px 10px; }
}

@media (max-width: 800px) {
  .wind-card { border-radius: 8px; }
  .wind-col-header,
  .wind-row { padding: 3px 8px; }
  .wind-row .wind-col-alt { font-size: 12.5px; }
  .wind-row .wind-col-dir { font-size: 12.5px; }
  .wind-row .wind-col-spd { font-size: 12.5px; }
  .wind-col { font-size: 10.5px; }
  .wind-arrow { font-size: 12px; }
}

.legend {
  position: absolute;
  bottom: 1rem;
  left: 1rem;
  background: var(--hub-surface);
  border: 1px solid var(--hub-border);
  border-radius: var(--radius-sm);
  padding: 0.6rem 0.85rem;
  font-size: 0.85rem;
  color: var(--hub-text-secondary);
  box-shadow: var(--hub-card-shadow);
}
.legend .bar {
  display: inline-block;
  width: 140px;
  height: 8px;
  background: linear-gradient(to right, #2e7adf, #5bb4e5, #1a7f37, #d29922, #d64545);
  border-radius: 4px;
  vertical-align: middle;
  margin: 0 0.4rem;
}

body.bigscreen .dash { grid-template-columns: 1fr; }
body.bigscreen .dash aside { display: none; }
body.bigscreen .dash header .stats { font-size: 1.4rem; }

/* ============================== Balloon markers ============================
 * Wrap is what maplibre uses as the Marker root element. The dot is the
 * coloured circle that sits at the geographic point. The label floats above
 * the dot — it MUST be `position: absolute` or it expands to fill the
 * marker wrap's containing block (the map) and produces full-width white
 * bars across the screen. See dashboard.js#upsertMarker.
 * -------------------------------------------------------------------------- */
.balloon-wrap {
  position: relative;
  width: 18px;
  height: 18px;
  cursor: pointer;
}
.balloon-dot {
  position: absolute;
  inset: 0;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  border: 2px solid #fff;
  box-shadow: 0 1px 6px rgba(0, 0, 0, 0.5);
  background: #888;
}
.balloon-label {
  position: absolute;
  left: 50%;
  bottom: 100%;
  margin-bottom: 4px;
  transform: translateX(-50%);
  background: var(--hub-surface);
  color: var(--hub-text);
  border: 1px solid var(--hub-border);
  border-radius: 0.4rem;
  padding: 0.05rem 0.4rem;
  font-size: 0.72rem;
  font-weight: 600;
  line-height: 1.2;
  white-space: nowrap;
  pointer-events: none;
  box-shadow: var(--hub-card-shadow);
}

/* ============================== Theme toggle ============================== */
.theme-toggle {
  padding: 0.4rem 0.55rem;
  min-width: 36px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.theme-toggle svg {
  width: 16px;
  height: 16px;
  display: block;
  color: currentColor;
}
.theme-toggle .theme-icon-sun  { display: none; }
.theme-toggle .theme-icon-moon { display: block; }
html[data-theme="dark"] .theme-toggle .theme-icon-sun  { display: block; }
html[data-theme="dark"] .theme-toggle .theme-icon-moon { display: none; }

/* ============================== Dark-mode polish ============================
 * The token system already flips most surfaces, but a handful of layered
 * pieces (the wind-sounding "dark island", the balloon-marker label pill,
 * the demo banner) need bespoke tuning so the dark theme reads as a
 * coherent dark UI rather than a stack of competing dark layers.
 * -------------------------------------------------------------------------- */
html[data-theme="dark"] .wind-card {
  background: #0a0e13;
  border: 1px solid var(--hub-border);
  box-shadow: none;
}
html[data-theme="dark"] .wind-col-header {
  border-bottom-color: rgba(255, 255, 255, 0.10);
}
html[data-theme="dark"] .wind-footer {
  background: rgba(255, 255, 255, 0.03);
}

html[data-theme="dark"] .balloon-label {
  background: rgba(22, 27, 34, 0.92);
  color: var(--hub-text);
  border-color: var(--hub-border-strong);
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.55);
}
html[data-theme="dark"] .balloon-dot {
  border-color: rgba(13, 17, 23, 0.95);
  box-shadow: 0 1px 6px rgba(0, 0, 0, 0.7);
}

html[data-theme="dark"] .legend {
  background: var(--hub-surface);
  border-color: var(--hub-border);
  color: var(--hub-text-secondary);
}

html[data-theme="dark"] .feed-indicator {
  background: var(--hub-surface-muted);
}

html[data-theme="dark"] #metarCard .metar-raw {
  background: var(--hub-surface-muted);
  border-color: var(--hub-border);
  color: var(--hub-text-secondary);
}

html[data-theme="dark"] .dash header {
  backdrop-filter: blur(6px);
}

/* MapLibre attribution + nav controls — let MapLibre's own CSS pick the
 * surface but darken the card chrome to match the dashboard panels. */
html[data-theme="dark"] .maplibregl-ctrl-attrib,
html[data-theme="dark"] .maplibregl-ctrl-group {
  background: rgba(22, 27, 34, 0.92);
  color: var(--hub-text);
}
html[data-theme="dark"] .maplibregl-ctrl-attrib a {
  color: var(--hub-accent);
}
html[data-theme="dark"] .maplibregl-ctrl-group button {
  filter: invert(0.92) hue-rotate(180deg);
}

/* ============================== Auth & landing ============================== */
.auth-bg {
  min-height: 100vh;
  background: linear-gradient(165deg, #ffffff 0%, #eef6f9 55%, #fff4e6 100%);
}
html[data-theme="dark"] .auth-bg {
  background: linear-gradient(165deg, #161b22 0%, #0d1117 55%, #1a1208 100%);
}

.center-wrap {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: calc(100vh - 64px);
  padding: 2rem 1.5rem;
}
.center-wrap .card {
  width: 100%;
  max-width: 420px;
  padding: 1.6rem 1.6rem 1.4rem;
  box-shadow: 0 8px 28px rgba(30, 58, 71, 0.10), var(--hub-card-shadow);
}
.center-wrap .card h2 {
  margin: 0 0 0.35rem;
  font-size: 1.35rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--hub-text);
}
.center-wrap .card p { color: var(--hub-text-secondary); margin: 0 0 1rem; }

.auth-eyebrow {
  display: inline-block;
  font-size: 0.66rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--hub-eyebrow);
  margin-bottom: 0.4rem;
}

.landing-hero {
  text-align: center;
  padding: 4rem 1rem 2rem;
}
.landing-hero h1 {
  font-size: 2.6rem;
  margin: 0 0 0.5rem;
  letter-spacing: -0.02em;
  color: var(--hub-text);
}
.landing-hero p { color: var(--hub-text-secondary); max-width: 640px; margin: 0 auto; }

.landing-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1rem;
  padding: 2rem 1rem 4rem;
  max-width: 1100px;
  margin: 0 auto;
}
.landing-grid h3 { margin-top: 0; }

@media (max-width: 800px) {
  .landing-grid { grid-template-columns: 1fr; }
  .dash { grid-template-columns: 1fr; }
  .dash aside { border-left: none; border-top: 1px solid var(--hub-border); }
}

/* ============================== Page header (admin) ============================== */
.page-eyebrow {
  display: inline-block;
  font-size: 0.66rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--hub-eyebrow);
  margin-bottom: 0.35rem;
}
.page-title {
  margin: 0 0 0.4rem;
  font-size: 1.45rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--hub-text);
  line-height: 1.2;
}
.page-lede {
  max-width: 40rem;
  color: var(--hub-text-secondary);
  margin: 0;
  font-size: 0.9rem;
  line-height: 1.5;
}
