/* base.css -- resets, layout shell. Component styles live in components/. */

*, *::before, *::after { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  min-height: 100%;
}

body {
  background: var(--housing);
  color: var(--legend);
  font-family: var(--f-body);
  font-size: var(--t-md);
  line-height: 1.5;
}

h1, h2, h3, .stat__value, .eyebrow {
  font-family: var(--f-display);
}

a { color: inherit; }

button, input {
  font-family: inherit;
  font-size: inherit;
  color: inherit;
}

:focus-visible {
  outline: 2px solid var(--pace);
  outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
}

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

.app-main {
  flex: 1;
  padding: var(--s-8);
  max-width: 960px;
  margin: 0 auto;
  width: 100%;
}

.eyebrow {
  font-size: var(--t-xs);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 0 0 var(--s-2);
}

.card {
  background: var(--plate);
  border-radius: var(--r-lg);
  box-shadow: var(--e-1);
  padding: var(--s-6);
}

.form-field {
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
  margin-bottom: var(--s-4);
}

.form-field label {
  font-size: var(--t-sm);
  color: var(--muted);
}

.form-field input {
  background: var(--housing);
  border: 1px solid var(--plate-hi);
  border-radius: var(--r-sm);
  padding: var(--s-3);
}

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--hit);
  color: var(--housing);
  border: none;
  border-radius: var(--r-sm);
  box-shadow: var(--e-key);
  padding: var(--s-3) var(--s-6);
  font-weight: 600;
  cursor: pointer;
  transition: transform var(--dur-fast) var(--ease);
}

.btn:active {
  transform: translateY(2px);
}

/* Ghost variant: pairs with .btn (e.g. class="btn btn--ghost") for a
   secondary action next to a primary one. Lives here, not in a page
   component file, since it's already referenced from several pages that
   don't all load the same component stylesheet. */
.btn--ghost {
  background: none;
  box-shadow: inset 0 0 0 1px var(--plate-hi);
  color: var(--muted);
}

.btn--ghost:hover { color: var(--legend); }

/* Destructive actions only. --miss is reserved for errors and never used
   decoratively (brief §5), and an irreversible delete is exactly the case
   that earns it. Outlined rather than filled so it can't be mistaken for the
   page's primary action. */
.btn--danger {
  background: none;
  box-shadow: inset 0 0 0 1px rgb(255 90 78 / 0.45);
  color: var(--miss);
}

.btn--danger:hover { background: rgb(255 90 78 / 0.10); }

.alert {
  border-radius: var(--r-sm);
  padding: var(--s-3) var(--s-4);
  margin-bottom: var(--s-4);
  font-size: var(--t-sm);
}

.alert--error {
  background: rgb(255 90 78 / 0.12);
  color: var(--miss);
  border: 1px solid rgb(255 90 78 / 0.35);
}

.alert--info {
  background: rgb(94 224 192 / 0.10);
  color: var(--pace);
  border: 1px solid rgb(94 224 192 / 0.30);
}

.alert--success {
  background: rgb(242 179 61 / 0.10);
  color: var(--hit);
  border: 1px solid rgb(242 179 61 / 0.30);
}

.stat {
  display: flex;
  flex-direction: column;
  gap: var(--s-1);
}

.stat__value {
  font-size: var(--t-2xl);
  color: var(--legend);
}

.stat__label {
  font-size: var(--t-xs);
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

/* ---------- layout helpers ----------
   Auto-fit grids so a row of stats or cards reflows to one column on a phone
   without a media query at every call site. */

.stat-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: var(--s-4);
}

.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: var(--s-4);
}

/* ---------- data table ----------
   Generalised from .history-table (progress.css), which had exactly these
   rules. Six views were hand-inlining `style="width:100%;font-size:..."` on a
   <table> instead; this is that markup's home. */

.data-table {
  width: 100%;
  font-size: var(--t-sm);
  border-collapse: collapse;
}

.data-table th {
  text-align: left;
  color: var(--muted);
  font-weight: normal;
  font-size: var(--t-xs);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  padding: var(--s-2);
  border-bottom: 1px solid var(--plate-hi);
}

.data-table td {
  padding: var(--s-2);
  border-bottom: 1px solid var(--plate-hi);
}

.data-table--mono { font-family: var(--f-mono); }
.data-table .is-numeric { text-align: right; font-variant-numeric: tabular-nums; }

/* ---------- pill ----------
   Small status chip: match state, tournament format, anti-cheat flag. */

.pill {
  display: inline-block;
  padding: 2px var(--s-2);
  border-radius: 999px;
  font-size: var(--t-xs);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  background: var(--plate-hi);
  color: var(--muted);
}

.pill--live { background: rgb(242 179 61 / 0.16); color: var(--hit); }
.pill--good { background: rgb(94 224 192 / 0.16); color: var(--pace); }
.pill--bad { background: rgb(255 90 78 / 0.16); color: var(--miss); }

/* ---------- empty state ----------
   Brief §5 copy rule: an empty state names the next action rather than just
   reporting emptiness. */

.empty-state {
  text-align: center;
  padding: var(--s-8) var(--s-4);
  color: var(--muted);
}

.empty-state__title {
  font-family: var(--f-display);
  color: var(--legend);
  margin: 0 0 var(--s-2);
  font-size: var(--t-md);
}

.empty-state p { margin: 0 0 var(--s-4); font-size: var(--t-sm); }

/* ---------- public shell (guest header/footer, layouts/main.php) ---------- */

.app-shell--public {
  flex-direction: column;
}

.public-header {
  display: flex;
  align-items: center;
  gap: var(--s-6);
  padding: var(--s-4) var(--s-8);
  border-bottom: 1px solid var(--plate-hi);
  background: var(--plate);
}

.public-header__brand {
  font-family: var(--f-display);
  font-size: var(--t-lg);
  color: var(--legend);
  text-decoration: none;
}
.public-header__brand span { color: var(--pace); }

.public-header__nav {
  display: flex;
  gap: var(--s-6);
  flex: 1;
}
.public-header__nav a {
  color: var(--muted);
  text-decoration: none;
  font-size: var(--t-sm);
}
.public-header__nav a:hover,
.public-header__nav a.is-active { color: var(--legend); }

.public-header__auth {
  display: flex;
  align-items: center;
  gap: var(--s-3);
}
.public-header__teacher-link {
  color: var(--muted);
  text-decoration: none;
  font-size: var(--t-sm);
  white-space: nowrap;
}
.public-header__teacher-link:hover,
.public-header__teacher-link.is-active { color: var(--legend); }

@media (max-width: 640px) {
  .public-header { flex-wrap: wrap; gap: var(--s-3); padding: var(--s-4); }
  .public-header__nav { order: 3; width: 100%; gap: var(--s-4); }
}

.site-footer {
  margin-top: auto;
  padding: var(--s-6) var(--s-8);
  border-top: 1px solid var(--plate-hi);
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--s-3);
}

.site-footer__links {
  display: flex;
  gap: var(--s-4);
}
.site-footer__links a {
  color: var(--muted);
  text-decoration: none;
  font-size: var(--t-sm);
}
.site-footer__links a:hover { color: var(--legend); }

.site-footer__meta {
  color: var(--muted);
  font-size: var(--t-xs);
  margin: 0;
}

/* ---------- public content pages (landing/about/guides) ---------- */

.public-hero {
  padding: var(--s-12) 0 var(--s-8);
  text-align: center;
}
.public-hero h1 {
  font-family: var(--f-display);
  font-size: var(--t-hero);
  color: var(--legend);
  margin: var(--s-4) 0;
  line-height: 1.1;
}
.public-hero p {
  color: var(--muted);
  font-size: var(--t-lg);
  max-width: 640px;
  margin: 0 auto var(--s-6);
}
.public-hero__actions {
  display: flex;
  gap: var(--s-3);
  justify-content: center;
  flex-wrap: wrap;
}

.public-article {
  max-width: 720px;
  margin: 0 auto;
  line-height: 1.7;
}
.public-article h2 {
  font-family: var(--f-display);
  color: var(--legend);
  margin-top: var(--s-12);
}
.public-article p { color: var(--legend); margin: var(--s-4) 0; }
.public-article ul, .public-article ol { color: var(--legend); padding-left: var(--s-6); }
.public-article li { margin: var(--s-2) 0; }

/* ---------- ad slots (Ads::unit(), app/Core/Ads.php) ---------- */

.ad-slot {
  display: block;
  margin: var(--s-6) auto;
  max-width: 720px;
  text-align: center;
}
.ad-slot::before {
  content: "Advertisement";
  display: block;
  font-size: var(--t-xs);
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  margin-bottom: var(--s-2);
}
/* Reserved space so the box exists at first paint -- the unit itself is an
   iframe injected after the AdSense script runs, and without a min-height the
   page jumps when it fills. Two sizes: an in-article unit is narrower than a
   full-width footer/hub placement. */
.ad-slot--article ins.adsbygoogle { min-height: 100px; }
.ad-slot--footer ins.adsbygoogle { min-height: 280px; }
