/* WARDOGS NOW shared components.
   Loaded by both shells, after tokens.css and before either shell's own stylesheet.

   Why this file exists. The admin console and the public site grew two vocabularies for the same
   things: .btn and .b for a button, .card and .panel for a surface, .kicker and .eyebrow for a
   section label. Worse, .dot and .pager were each defined twice, once here and once there, and
   because public pages loaded both stylesheets, which definition won was decided by link order
   rather than by anyone's intent. A server status dot rendered correctly by luck.

   Everything shared is defined once here. The admin's class names are kept and aliased onto the
   public ones rather than renamed, because thirteen admin templates carry about a hundred usages
   between them, and restyling reaches every one with no markup churn and no chance of missing one.
   The rendered result is identical either way.

   The alias blocks are marked. If you are adding something new, use the public name. */

/* ---------- reset and base ---------- */
* { box-sizing: border-box; }
html, body {
  margin: 0; padding: 0;
  background: var(--bg-0); color: var(--text-hi);
  font-family: var(--sans); font-size: 15px; line-height: 1.6;
  min-height: 100%; -webkit-font-smoothing: antialiased;
}
img, svg { display: block; }
hr { border: none; border-top: 1px solid var(--line); margin: 1rem 0; }
small { color: var(--text-mid); }
/* .dim was --text-dim, which is 3.19 against the page and fails AA at every size the site
   actually uses it. Tertiary text that cannot be read is not serving anyone, so .dim and
   .muted are now the same readable secondary. --text-dim survives for non text use: icon
   strokes, hairlines, and anything where contrast is not legibility. */
.dim, .muted { color: var(--text-mid); }
.right { text-align: right; }
.nowrap { white-space: nowrap; }
.spacer, .flex1 { flex: 1; }

/* Visually hidden but read aloud. Used for status dots, which are a colour to a sighted reader and
   must be a word to everyone else. */
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* ---------- typography ---------- */
h1, h2, h3, h4 { margin: 0 0 .5rem; letter-spacing: -.01em; font-weight: 700; line-height: 1.25; }
h1 { font-size: 1.7rem; letter-spacing: -.02em; }
h2 { font-size: 1.15rem; }
h3 { font-size: 1rem; }
.mono, code, pre, .num { font-family: var(--mono); }
/* Digits that sit in columns have to line up, or every row jitters as the numbers change. */
.num { font-variant-numeric: tabular-nums; }
a { color: var(--accent-cool); text-decoration: none; }
a:hover { color: var(--accent); }

/* The display face, used for headings that carry the brand rather than just structure. */
.h-display {
  font-family: var(--display);
  letter-spacing: .005em;
  text-transform: uppercase;
  text-wrap: balance;
}

/* Section label. Plain type doing the work, deliberately not a pill: this site has no badges. */
.eyebrow {
  font-family: var(--mono); font-size: .68rem; letter-spacing: .26em;
  text-transform: uppercase; color: var(--accent); font-weight: 600;
}
.eyebrow.quiet { color: var(--text-mid); }

/* State as a word rather than a chip. */
.state { font-family: var(--mono); font-size: .68rem; letter-spacing: .1em; text-transform: uppercase; }
.state.pending  { color: var(--warn); }
.state.approved { color: var(--ok); }
.state.declined { color: var(--danger); }
.state.hidden   { color: var(--text-mid); }
.state.accepted { color: var(--ok); }
.state.partial  { color: #78b8e6; }
.state.rejected { color: var(--danger); }
.state.withdrawn { color: var(--text-mid); }

/* ---------- buttons ---------- */
.b {
  display: inline-flex; align-items: center; gap: 8px; cursor: pointer;
  font-family: var(--mono); font-size: .74rem; font-weight: 700;
  letter-spacing: .08em; text-transform: uppercase;
  padding: 11px 18px; border-radius: var(--radius-sm);
  border: 1px solid transparent; transition: .14s; text-decoration: none;
}
.b-primary { background: var(--accent); color: #0F1113; }
.b-primary:hover { background: var(--accent-2); color: #0F1113; }
.b-ghost { border-color: var(--line2); color: var(--text-hi); background: color-mix(in srgb, var(--bg-2) 55%, transparent); }
.b-ghost:hover { border-color: var(--accent); color: var(--accent); }
.b-danger { border-color: color-mix(in srgb, var(--danger) 55%, var(--line2)); color: var(--danger); background: color-mix(in srgb, var(--bg-2) 55%, transparent); }
.b-danger:hover { background: var(--danger); color: #0F1113; }
.b-sm { padding: 8px 13px; font-size: .68rem; }
.b[disabled], .b.is-disabled { opacity: .45; cursor: not-allowed; pointer-events: none; }
.b:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* ALIAS: the admin console's button. Same rules, older name. */
.btn {
  display: inline-flex; align-items: center; gap: 8px; cursor: pointer;
  font-family: var(--mono); font-size: .74rem; font-weight: 700;
  letter-spacing: .08em; text-transform: uppercase;
  padding: 11px 18px; border-radius: var(--radius-sm);
  border: 1px solid var(--line2); color: var(--text-hi);
  background: color-mix(in srgb, var(--bg-2) 55%, transparent);
  transition: .14s; text-decoration: none;
}
.btn:hover { border-color: var(--accent); color: var(--accent); }
.btn.primary { background: var(--accent); border-color: var(--accent); color: #0F1113; }
.btn.primary:hover { background: var(--accent-2); color: #0F1113; }
.btn.danger { color: var(--danger); border-color: color-mix(in srgb, var(--danger) 55%, var(--line2)); }
.btn.danger:hover { background: var(--danger); color: #0F1113; }
.btn.ghost { color: var(--text-hi); }
.btn.small { padding: 8px 13px; font-size: .68rem; }
.btn.big { padding: 13px 22px; font-size: .82rem; }
.btn[disabled] { opacity: .45; cursor: not-allowed; pointer-events: none; }
.btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.btn-row { display: flex; gap: .55rem; flex-wrap: wrap; align-items: center; }

/* ---------- surfaces ---------- */
.panel {
  background: var(--bg-1); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 24px;
}
.panel.tight { padding: 18px; }
.lede { color: var(--text-mid); max-width: 62ch; }
.prose { color: var(--text-mid); line-height: 1.75; white-space: pre-wrap; overflow-wrap: anywhere; }

/* ALIAS: the admin console's surfaces. */
.card {
  background: var(--bg-1); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 1.15rem 1.3rem; margin-bottom: 1.1rem;
}
.card.hdr { display: flex; align-items: center; justify-content: space-between; gap: 1rem; padding: .95rem 1.3rem; }
.card h2 { font-size: 1.1rem; }
.tile {
  background: var(--bg-1); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 1.1rem 1.2rem; transition: .14s; display: block;
}
.tile:hover { border-color: var(--line2); transform: translateY(-2px); }
.tile h3 { font-size: .95rem; }
.tile .row { display: flex; justify-content: space-between; align-items: baseline; gap: .5rem; }
.tile .stat { font-family: var(--mono); font-size: 1.5rem; font-weight: 700; color: var(--accent); }
.tile .sub, .tile .meta { color: var(--text-mid); font-size: .78rem; font-family: var(--mono); }
.tiles { display: grid; gap: .9rem; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); }

/* ALIAS: .title is on 34 admin headings. It is a heading, not a label. */
.title { color: var(--text-hi); font-weight: 700; letter-spacing: -.01em; line-height: 1.25;
         font-family: var(--display); }

/* ---------- status dots ----------
   Three states, not two. While a server's probe is switched off, is_online is NULL and the honest
   answer is that nobody knows, which must never render as offline. Defined once, here. */
.dot { width: 8px; height: 8px; border-radius: 50%; flex: none; display: inline-block; vertical-align: middle; }
.dot.live, .dot.ok   { background: var(--live); box-shadow: 0 0 0 3px color-mix(in srgb, var(--live) 20%, transparent); }
.dot.dead, .dot.off  { background: var(--dead); }
.dot.unknown         { background: transparent; border: 1px solid var(--unknown); }
.dot.warn            { background: var(--warn); }

/* ---------- forms ---------- */
label { display: block; margin-bottom: .7rem; font-family: var(--mono);
        text-transform: uppercase; letter-spacing: .1em; font-size: .7rem; color: var(--text-mid); }
input[type=text], input[type=password], input[type=number], input[type=email],
input[type=url], input[type=date], input[type=datetime-local], input[type=time],
input[type=month], input[type=week], input[type=search], textarea, select {
  width: 100%; margin-top: .35rem; padding: .6rem .75rem;
  background-color: var(--bg-2); border: 1px solid var(--line2); border-radius: var(--radius-sm);
  color: var(--text-hi); font-family: var(--sans); font-size: .95rem;
}

select {
  appearance: none;
  padding-right: 2.5rem;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='m1 1 5 5 5-5' fill='none' stroke='%2393A0AC' stroke-width='1.5' stroke-linecap='square'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right .85rem center;
  background-size: 12px 8px;
  cursor: pointer;
}

select[multiple],
select[size]:not([size="1"]) { padding-right: .75rem; background-image: none; }
select option,
select optgroup { background: #151a1e; color: var(--text-hi); }
select option:checked { background: #273039; color: #fff; }
select:disabled { cursor: not-allowed; opacity: .58; }

input[type=date],
input[type=datetime-local],
input[type=time],
input[type=month],
input[type=week] { color-scheme: dark; }
input[type=date]::-webkit-calendar-picker-indicator,
input[type=datetime-local]::-webkit-calendar-picker-indicator,
input[type=time]::-webkit-calendar-picker-indicator,
input[type=month]::-webkit-calendar-picker-indicator,
input[type=week]::-webkit-calendar-picker-indicator {
  padding: 5px;
  border-radius: 4px;
  opacity: .72;
  cursor: pointer;
}
input[type=date]::-webkit-calendar-picker-indicator:hover,
input[type=datetime-local]::-webkit-calendar-picker-indicator:hover,
input[type=time]::-webkit-calendar-picker-indicator:hover,
input[type=month]::-webkit-calendar-picker-indicator:hover,
input[type=week]::-webkit-calendar-picker-indicator:hover { background-color: rgba(255, 255, 255, .08); opacity: 1; }
input::-webkit-date-and-time-value { min-height: 1.35em; text-align: left; }

input[type=file] {
  width: 100%;
  padding: 7px;
  border: 1px solid var(--line2);
  border-radius: var(--radius-sm);
  background: var(--bg-2);
  color: var(--text-mid);
  font-family: var(--sans);
}
input[type=file]::file-selector-button {
  margin-right: 12px;
  padding: 8px 12px;
  border: 1px solid var(--line2);
  border-radius: 5px;
  background: var(--bg-1);
  color: var(--text-hi);
  font: 600 .7rem/1 var(--mono);
  letter-spacing: .07em;
  text-transform: uppercase;
  cursor: pointer;
}
input[type=file]::file-selector-button:hover { border-color: var(--accent); color: var(--accent); }
input[type=checkbox], input[type=radio] { accent-color: var(--accent); }
input:focus, textarea:focus, select:focus,
input[type=file]:focus-within {
  outline: none; border-color: var(--accent);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent) 26%, transparent);
}
textarea { line-height: 1.65; }

/* The public form field wrapper, which labels itself rather than relying on the bare label rule. */
.field { display: flex; flex-direction: column; gap: 6px; margin-bottom: 0; }
.field > span { font-family: var(--mono); font-size: .68rem; letter-spacing: .14em;
                text-transform: uppercase; color: var(--text-mid); }
.field input, .field select, .field textarea { margin-top: 0; padding: 10px 12px; font-size: .92rem; }
.field textarea { min-height: 150px; resize: vertical; }
.field .hint { color: var(--text-mid); font-size: .78rem; line-height: 1.5; }
.field.row { flex-direction: row; align-items: center; gap: 9px; }
.f-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 16px; }
.f-grid .wide { grid-column: 1 / -1; }
@media (max-width: 720px) { .f-grid { grid-template-columns: 1fr; } }

.grid { display: grid; gap: 1rem; }
.grid-2 { grid-template-columns: repeat(2, minmax(0,1fr)); }
.grid-3 { grid-template-columns: repeat(3, minmax(0,1fr)); }
@media (max-width: 740px) { .grid-2, .grid-3 { grid-template-columns: 1fr; } }

/* ---------- tables ---------- */
table.t {
  width: 100%; border-collapse: separate; border-spacing: 0;
  background: var(--bg-1); border: 1px solid var(--line);
  border-radius: var(--radius); overflow: hidden;
}
table.t th, table.t td { padding: .6rem .8rem; text-align: left; border-bottom: 1px solid var(--line); vertical-align: middle; }
table.t thead th { background: var(--bg-2); font-family: var(--mono); text-transform: uppercase;
                   letter-spacing: .1em; font-size: .68rem; color: var(--text-mid); font-weight: 700; }
table.t tbody tr:last-child td { border-bottom: 0; }
table.t tbody tr:hover td { background: var(--bg-hover); }
table.t td.num { text-align: right; }
table.t td.actions { text-align: right; white-space: nowrap; }
.tablewrap { overflow-x: auto; }

/* ---------- pagination ----------
   Defined once, here. It used to exist in both stylesheets with different padding. */
.pager { display: flex; gap: 8px; justify-content: center; margin-top: 24px; flex-wrap: wrap; }
.pager a, .pager span {
  padding: 8px 13px; border-radius: var(--radius-sm); border: 1px solid var(--line2);
  font-family: var(--mono); font-size: .76rem; color: var(--text-mid);
}
.pager a:hover { border-color: var(--accent); color: var(--accent); }
.pager .cur { background: var(--accent); border-color: var(--accent); color: #0F1113; font-weight: 700; }

/* ---------- flash messages ---------- */
.flash { padding: .8rem 1.05rem; margin-bottom: 1rem; border: 1px solid var(--line2);
         border-radius: var(--radius-sm); background: var(--bg-1); font-size: .9rem; }
.flash.ok, .flash.success { border-color: color-mix(in srgb, var(--ok) 55%, var(--line2)); background: color-mix(in srgb, var(--ok) 10%, var(--bg-1)); }
.flash.error { border-color: color-mix(in srgb, var(--danger) 55%, var(--line2)); background: color-mix(in srgb, var(--danger) 10%, var(--bg-1)); }
.flash.warn  { border-color: color-mix(in srgb, var(--warn) 55%, var(--line2)); background: color-mix(in srgb, var(--warn) 10%, var(--bg-1)); }
.flash.info  { border-color: color-mix(in srgb, var(--accent-cool) 55%, var(--line2)); background: color-mix(in srgb, var(--accent-cool) 10%, var(--bg-1)); }

/* ---------- small bits ---------- */
[hidden] { display: none !important; }

.tag { display: inline-block; padding: 3px 9px; background: var(--bg-2); border: 1px solid var(--line2);
       border-radius: var(--radius-pill); font-family: var(--mono); font-size: .68rem; color: var(--text-mid); }

/* Share row and its desktop menu */
.share-controls { position: relative; display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.share-controls [data-share-status] { color: var(--text-mid); font-size: .78rem; }
.share-menu { position: absolute; left: 0; top: calc(100% + 6px); z-index: 30; display: grid; min-width: 260px; padding: 6px 0; border: 1px solid var(--line2); border-radius: var(--radius-sm); background: var(--bg-1); box-shadow: 0 12px 32px rgba(0, 0, 0, .45); }
.share-menu[hidden] { display: none; }
.share-menu a, .share-menu button { display: block; width: 100%; padding: 10px 14px; border: 0; background: none; color: var(--text-hi); font: 500 .86rem var(--sans); text-align: left; text-decoration: none; cursor: pointer; }
.share-menu a:hover, .share-menu button:hover { background: var(--bg-2); color: var(--accent); }
.share-menu button { border-bottom: 1px solid var(--line); }
