/* Reset + global base: typography, forms, buttons, tags, focus, scrollbar. */

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

html {
  font-size: 16px;
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

body {
  font-family: var(--font-body);
  font-size: var(--text-base);
  background-color: var(--surface-0);
  color: var(--color-parchment);
  line-height: var(--leading-normal);
  min-height: 100vh;
  font-feature-settings: "ss01", "cv01", "cv11";
}

/* ── Selection + focus ──────────────────────────── */

::selection {
  background-color: var(--color-amber-30);
  color: var(--color-parchment);
}

:focus:not(:focus-visible) { outline: none; }

:focus-visible {
  outline: 2px solid var(--color-amber);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}

/* ── Scrollbar (webkit) ─────────────────────────── */

::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
  background: rgba(232, 213, 163, 0.08);
  border-radius: var(--radius-full);
  border: 2px solid transparent;
  background-clip: padding-box;
}
::-webkit-scrollbar-thumb:hover {
  background: var(--border-strong);
  background-clip: padding-box;
  border: 2px solid transparent;
}

* { scrollbar-width: thin; scrollbar-color: rgba(232, 213, 163, 0.12) transparent; }

/* ── Typography ─────────────────────────────────── */

h1, h2, h3, h4, h5, h6 {
  font-family: var(--font-display);
  font-weight: 600;
  line-height: var(--leading-tight);
  color: var(--color-parchment);
  letter-spacing: var(--tracking-tight);
}

h1 { font-size: var(--text-3xl); letter-spacing: 0; }
h2 { font-size: var(--text-2xl); }
h3 { font-size: var(--text-xl); }
h4 { font-size: var(--text-lg); }
h5 { font-size: var(--text-base); }
h6 { font-size: var(--text-sm); }

p { line-height: var(--leading-normal); }
p + p { margin-top: var(--space-3); }

a {
  color: var(--color-amber);
  text-decoration: none;
  transition: color var(--transition-fast);
}
a:hover { color: var(--color-sunflower); }

strong, b { font-weight: 600; color: var(--color-parchment); }
em, i { font-style: italic; }
small { font-size: var(--text-xs); color: var(--color-ash); }

code, kbd, samp {
  font-family: var(--font-mono);
  font-size: 0.92em;
  background-color: var(--surface-inset);
  color: var(--color-parchment);
  padding: 0.1em 0.35em;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border-subtle);
}

pre {
  font-family: var(--font-mono);
  background-color: var(--surface-inset);
  padding: var(--space-4);
  border-radius: var(--radius-md);
  overflow-x: auto;
  border: 1px solid var(--border-subtle);
  line-height: var(--leading-snug);
}
pre code { background: none; padding: 0; border: none; }

ul, ol {
  padding-left: var(--space-5);
  line-height: var(--leading-normal);
}
li + li { margin-top: var(--space-1); }

img, video, svg { max-width: 100%; display: block; }

hr {
  border: none;
  border-top: 1px solid var(--border-subtle);
  margin: var(--space-6) 0;
}

hr.hr-tight { margin: var(--space-2) 0; }

/* ── Section heading utility (was h2 default) ───── */

.section-eyebrow,
.eyebrow {
  display: inline-block;
  font-family: var(--font-display);
  font-size: var(--text-xs);
  color: var(--color-amber);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wider);
  font-weight: 600;
}

/* ── Buttons — single source of truth ───────────── */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  height: 36px;
  padding: 0 var(--space-4);
  font-family: var(--font-body);
  font-size: var(--text-sm);
  font-weight: 500;
  line-height: 1;
  letter-spacing: 0;
  color: var(--color-parchment);
  background-color: transparent;
  border: var(--border-width-bold) solid transparent;
  border-radius: var(--radius-md);
  cursor: pointer;
  text-decoration: none;
  white-space: nowrap;
  user-select: none;
  /* Base transition — button variants below overlay their own timings for
     the properties they actually animate (fill vs. border vs. transform),
     so hover feels intentional per button role rather than one generic
     "everything fades" transition site-wide. */
  transition:
    background-color var(--transition-fast),
    border-color var(--transition-fast),
    color var(--transition-fast),
    box-shadow var(--transition-fast);
}

.btn:disabled,
.btn[aria-disabled="true"] {
  opacity: 0.5;
  pointer-events: none;
}

.btn:focus-visible {
  box-shadow: var(--focus-ring);
  outline: none;
}

/* Primary — solid amber. Hover deepens fill + lifts on the shadow token;
   active presses flat so the "click" reads as a real button press. */
.btn-primary, .btn--primary {
  background-color: var(--color-amber);
  border-color: var(--color-amber);
  color: var(--color-soil);
  font-weight: 600;
  box-shadow: var(--shadow-sm);
  transition:
    background-color var(--transition-base),
    border-color var(--transition-base),
    color var(--transition-base),
    box-shadow var(--transition-base),
    transform var(--transition-fast);
}
.btn-primary:hover, .btn--primary:hover {
  background-color: var(--color-sunflower);
  border-color: var(--color-sunflower);
  color: var(--color-soil);
  box-shadow: var(--shadow-hover);
}
@media (prefers-reduced-motion: no-preference) {
  .btn-primary:hover, .btn--primary:hover { transform: translateY(-1px); }
  .btn-primary:active, .btn--primary:active { transform: translateY(1px); box-shadow: none; }
}

/* Secondary — surface fill with subtle border. Hover elevates the surface
   one step and warms the border to accent, no lift — this is a supporting
   action, so it should feel calmer than primary. */
.btn-secondary, .btn--secondary {
  background-color: var(--surface-2);
  border-color: var(--border-strong);
  color: var(--color-parchment);
}
.btn-secondary:hover, .btn--secondary:hover {
  background-color: var(--surface-3);
  border-color: var(--border-amber);
  color: var(--color-cream);
}
@media (prefers-reduced-motion: no-preference) {
  .btn-secondary:active, .btn--secondary:active { transform: translateY(1px); }
}

/* Ghost — transparent until hover. Distinct treatment: hover animates
   an accent-tinted background wash in and firms up the border, without
   the surface-swap that secondary uses. Underline slides in under the
   label as a small microinteraction detail. */
.btn-ghost, .btn--ghost {
  background-color: transparent;
  border-color: var(--border-default);
  color: var(--color-parchment);
  position: relative;
}
.btn-ghost:hover, .btn--ghost:hover {
  background-color: var(--color-accent-08);
  border-color: var(--color-accent-30);
  color: var(--color-cream);
}
@media (prefers-reduced-motion: no-preference) {
  .btn-ghost:active, .btn--ghost:active { transform: scale(0.98); }
}

/* Outline — accent border, no fill. Hover flips to a filled state so the
   change is a state transition (empty → filled) rather than a colour
   nudge — different from ghost's wash-in. */
.btn-outline, .btn--outline {
  background-color: transparent;
  border-color: var(--color-amber-30);
  color: var(--color-amber);
  transition:
    background-color var(--transition-slow),
    border-color var(--transition-fast),
    color var(--transition-fast);
}
.btn-outline:hover, .btn--outline:hover {
  background-color: var(--color-amber);
  border-color: var(--color-amber);
  color: var(--color-soil);
}
@media (prefers-reduced-motion: no-preference) {
  .btn-outline:active, .btn--outline:active { transform: translateY(1px); }
}

/* Danger — destructive. Hover fully inverts (border-only → filled solid),
   a deliberately stronger commit signal than the other buttons because
   the action itself is destructive. */
.btn-danger, .btn--danger {
  background-color: transparent;
  border-color: var(--color-ember);
  color: var(--color-ember);
  transition:
    background-color var(--transition-base),
    border-color var(--transition-base),
    color var(--transition-base),
    box-shadow var(--transition-base);
}
.btn-danger:hover, .btn--danger:hover {
  background-color: var(--color-ember);
  color: var(--color-cream);
  box-shadow: 0 0 0 3px var(--color-wine-20);
}
@media (prefers-reduced-motion: no-preference) {
  .btn-danger:active, .btn--danger:active { transform: translateY(1px); box-shadow: none; }
}

/* Approve — affirmative commit, the vine-green counterpart to danger's ember.
   Filled from resting (this is a confirming action, not a reversible toggle
   like ghost/outline) with an elevation-only hover — no new color token, just
   brightness on the existing vine fill — since vine has no lighter sibling
   token the way sunflower/honey does for primary. Referenced as .btn--approve
   in admin/approvals but previously undefined, so it rendered as a bare
   transparent .btn with no affirmative signal at all. */
.btn-approve, .btn--approve {
  background-color: var(--color-vine);
  border-color: var(--color-vine);
  color: var(--color-cream);
  font-weight: 600;
  box-shadow: var(--shadow-sm);
  transition:
    box-shadow var(--transition-base),
    filter var(--transition-base),
    transform var(--transition-fast);
}
.btn-approve:hover, .btn--approve:hover {
  filter: brightness(1.18);
  box-shadow: var(--shadow-hover);
}
@media (prefers-reduced-motion: no-preference) {
  .btn-approve:hover, .btn--approve:hover { transform: translateY(-1px); }
  .btn-approve:active, .btn--approve:active { transform: translateY(1px); box-shadow: none; }
}

/* Discord OAuth — brand color */
.btn--discord {
  background-color: #5865F2;
  border-color: #5865F2;
  color: #fff;
  font-weight: 600;
}
.btn--discord:hover {
  background-color: #4752c4;
  border-color: #4752c4;
  color: #fff;
}

/* Sizes */
.btn-sm, .btn--sm {
  height: 28px;
  padding: 0 var(--space-3);
  font-size: var(--text-xs);
  gap: var(--space-1);
}
.btn--xs {
  height: 22px;
  padding: 0 var(--space-2);
  font-size: var(--text-xs);
  gap: var(--space-1);
}
.btn-lg, .btn--lg {
  height: 44px;
  padding: 0 var(--space-6);
  font-size: var(--text-base);
}
.btn--full { width: 100%; }
/* Icon-only — a distinct microinteraction: hover paints a soft accent
   ring inside the frame (via inset box-shadow) so it feels like the
   glyph is being "picked up", rather than the same background-swap
   every other button uses. */
.btn--icon {
  padding: 0;
  width: 36px;
  color: var(--color-ash);
  transition:
    color var(--transition-fast),
    background-color var(--transition-fast),
    box-shadow var(--transition-base);
}
.btn--icon:hover {
  color: var(--color-accent);
  background-color: var(--color-accent-08);
  box-shadow: inset 0 0 0 1px var(--color-accent-30);
}
@media (prefers-reduced-motion: no-preference) {
  .btn--icon:active { transform: scale(0.92); }
}

/* Muted — de-emphasised toggle state */
.btn--muted {
  opacity: 0.5;
}

/* Active filter / pressed state */
.btn--active {
  background-color: var(--color-amber-10);
  border-color: var(--color-amber);
  color: var(--color-amber);
}

/* ── Card utility ───────────────────────────────── */

.card {
  background-color: var(--surface-1);
  border: var(--border-width-bold) solid var(--border-default);
  border-radius: var(--radius-lg);
  padding: var(--space-5);
  transition:
    background-color var(--transition-fast),
    border-color var(--transition-fast),
    transform var(--transition-fast);
}

@media (prefers-reduced-motion: no-preference) {
  .card:hover {
    background-color: var(--surface-2);
    border-color: var(--border-strong);
    transform: translateY(-1px);
    box-shadow: var(--shadow-card);
  }
  .card:active { transform: translateY(0); box-shadow: none; }
}

/* ── Input focus micro-interaction ───────────────
   Adds a small lift on focus so the input feels like it grabs focus
   physically, not just recolours. Matches the button press character. */
@media (prefers-reduced-motion: no-preference) {
  input:focus,
  textarea:focus,
  select:focus {
    transform: translateY(-1px);
  }
  input, textarea, select {
    transition:
      border-color var(--transition-fast),
      box-shadow var(--transition-fast),
      background-color var(--transition-fast),
      transform var(--transition-fast);
  }
}

/* ── Site-wide scroll-driven reveal ─────────────
   Where the browser supports scroll-timeline / animation-timeline: view()
   (Chromium 115+, Safari TP), every content block in this list gets a
   short fade-up as it enters the viewport — no per-page JS controller,
   no per-page class opt-in, no observer running on scroll. Falls back
   silently to no animation on browsers without support (the block just
   appears). This intentionally does NOT touch heavy chrome (topbar,
   sidebar, modals) or already-animated containers (.reveal-block,
   .landing-section, .landing-strip). Reduced-motion users get nothing
   via the outer media query. */
@media (prefers-reduced-motion: no-preference) {
  @supports (animation-timeline: view()) {
    @keyframes surface-in {
      from { opacity: 0; transform: translateY(14px); }
      to   { opacity: 1; transform: translateY(0); }
    }

    .card,
    .stat-card,
    .server-card,
    .server-cards-row > *,
    .member-card,
    .member-row,
    .shop-card,
    .showcase-card,
    .house-card,
    .house-banner,
    .season-card,
    .season-house-card,
    .forum-post-card,
    .review-card,
    .activity-item,
    .profile-activity-item,
    .notification-row,
    .lore-chapter-row,
    .lore-submission-card,
    .lore-placement-card,
    .badge-card,
    .badge-admin-card,
    .profile-badge-card,
    .comment-card,
    .admin-ticket-card,
    .admin-emoji-card,
    .archive-banner,
    .season-banner,
    .profile-hero,
    .settings-section,
    .form-section,
    .profile-section,
    .comments-section,
    .season-gallery-section,
    .seasons-section,
    .pending-card,
    .auth-card {
      animation: surface-in linear both;
      animation-timeline: view();
      animation-range: entry 5% cover 25%;
    }
  }
}

/* ── Tags ───────────────────────────────────────── */

.tag {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: 2px var(--space-2);
  background-color: var(--color-white-05);
  color: var(--color-ash);
  font-size: var(--text-xs);
  font-weight: 500;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border-subtle);
  white-space: nowrap;
  letter-spacing: 0.02em;
}

.tag--success { background-color: var(--color-vine-20); color: var(--color-success-text); border-color: transparent; }
.tag--warning { background-color: var(--color-amber-10); color: var(--color-sunflower); border-color: transparent; }
.tag--danger  { background-color: var(--color-ember-20); color: var(--color-danger-text-strong); border-color: transparent; }
.tag--online  { background-color: rgba(74,103,65,0.25); color: var(--color-success-text); border-color: transparent; }
.tag--offline { background-color: var(--color-ember-20); color: var(--color-danger-text-strong); border-color: transparent; }
.tag--unknown { background-color: var(--color-white-05); color: var(--color-ash); border-color: transparent; }

.tag-list {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  list-style: none;
  padding: 0;
}

/* ── Badge pill (status) ────────────────────────── */

.badge {
  display: inline-block;
  padding: 2px var(--space-2);
  border-radius: var(--radius-sm);
  font-size: var(--text-xs);
  font-weight: 600;
  line-height: 1.4;
}
.badge--open   { background: var(--color-vine-20); color: var(--color-success-text); }
.badge--closed { background: var(--color-white-05); color: var(--color-ash); }

/* Lore submission review status — same pill, same semantics as badge--open/closed
   (vine = good, ember = stopped, white-05 = neutral), plus amber for "needs you". */
.badge--approved            { background: var(--color-vine-20); color: var(--color-success-text); }
.badge--pending              { background: var(--color-amber-10); color: var(--color-sunflower); }
.badge--feedback_requested  { background: var(--color-white-05); color: var(--color-amber); border: 1px solid var(--color-amber-30); }
.badge--rejected             { background: var(--color-ember-20); color: var(--color-danger-text-strong); }

/* ── Forms ──────────────────────────────────────── */

label {
  display: block;
  color: var(--color-ash);
  font-size: var(--text-xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
  margin-bottom: var(--space-2);
}

input[type="text"],
input[type="email"],
input[type="password"],
input[type="search"],
input[type="url"],
input[type="number"],
input[type="color"],
textarea,
select {
  width: 100%;
  height: 38px;
  background-color: var(--surface-inset);
  color: var(--color-parchment);
  border: var(--border-width-bold) solid var(--border-default);
  border-radius: var(--radius-md);
  padding: 0 var(--space-3);
  font-family: var(--font-body);
  font-size: var(--text-sm);
  line-height: 1;
  transition: border-color var(--transition-fast), box-shadow var(--transition-fast), background-color var(--transition-fast);
  appearance: none;
}

input[type="color"] {
  padding: 2px;
  cursor: pointer;
}

input:hover, textarea:hover, select:hover {
  border-color: var(--border-strong);
}

input:focus,
textarea:focus,
select:focus {
  outline: none;
  border-color: var(--color-amber);
  background-color: var(--color-soil);
  box-shadow: 0 0 0 3px var(--color-amber-10);
}

input:focus-visible,
textarea:focus-visible,
select:focus-visible {
  outline: 2px solid var(--color-amber);
  outline-offset: 2px;
  box-shadow: none;
}

input::placeholder,
textarea::placeholder {
  color: var(--color-ash);
  opacity: 0.6;
}

textarea {
  resize: vertical;
  min-height: 96px;
  padding: var(--space-3);
  height: auto;
  line-height: var(--leading-normal);
}

select {
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'><path d='M1 1l5 5 5-5' stroke='%239A8F7A' stroke-width='1.5' fill='none' stroke-linecap='round' stroke-linejoin='round'/></svg>");
  background-repeat: no-repeat;
  background-position: right var(--space-3) center;
  padding-right: var(--space-8);
  cursor: pointer;
}

/* Hide browser number-input spinners — they clash with the dark theme */
input[type="number"]::-webkit-inner-spin-button,
input[type="number"]::-webkit-outer-spin-button {
  -webkit-appearance: none;
  margin: 0;
}
input[type="number"] { -moz-appearance: textfield; }

/* Force dark colour-scheme so date/time pickers use system dark styles */
input[type="date"],
input[type="datetime-local"],
input[type="time"],
input[type="month"] {
  color-scheme: dark;
  color: var(--color-parchment);
}

/* Checkbox / radio — previously fully unstyled (bare OS default) despite
   every other input type going through the themed treatment above.
   accent-color re-themes the native control itself (no custom markup needed
   for the two checkboxes currently in the app), plus a deliberate
   focus-visible ring matching every other focusable control. */
input[type="checkbox"],
input[type="radio"] {
  width: 16px;
  height: 16px;
  accent-color: var(--color-amber);
  cursor: pointer;
  flex-shrink: 0;
}

input[type="checkbox"]:focus-visible,
input[type="radio"]:focus-visible {
  outline: 2px solid var(--color-amber);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}

.field, .form-group {
  margin-bottom: var(--space-4);
}

.field-hint, .form-hint {
  font-size: var(--text-xs);
  color: var(--color-ash);
  margin-top: var(--space-1);
}

.field-error {
  font-size: var(--text-xs);
  color: var(--color-danger-text-strong);
  margin-top: var(--space-1);
}

/* ── Flash messages ─────────────────────────────── */

.flash,
.flash-notice,
.flash-alert,
.flash--notice,
.flash--alert {
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  font-size: var(--text-sm);
  border-left: 3px solid;
  background-color: var(--surface-1);
}

.flash-notice, .flash--notice {
  border-color: var(--color-vine);
  color: var(--color-success-text-strong);
}

.flash-alert, .flash--alert {
  border-color: var(--color-ember);
  color: var(--color-danger-text);
}

/* ── Utility ────────────────────────────────────── */

.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;
}

.text-amber     { color: var(--color-amber); }
.text-sunflower { color: var(--color-sunflower); }
.text-ash       { color: var(--color-ash); }
.text-ember     { color: var(--color-ember); }
.text-vine      { color: var(--color-vine); }
.text-parchment { color: var(--color-parchment); }
.text-muted     { color: var(--color-ash); }
.text-display   { font-family: var(--font-display); }
.text-mono      { font-family: var(--font-mono); }
.text-center    { text-align: center; }
.text-xs        { font-size: var(--text-xs); }
.text-sm        { font-size: var(--text-sm); }
.muted          { color: var(--color-ash); font-size: var(--text-sm); }

/* ── Admin table ────────────────────────────────── */

.admin-table {
  display: block;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  width: 100%;
  border-collapse: collapse;
  font-size: var(--text-sm);
}

.admin-table th {
  text-align: left;
  padding: var(--space-2) var(--space-3);
  color: var(--color-ash);
  font-weight: 600;
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
  border-bottom: 1px solid var(--border-default);
  background-color: var(--surface-1);
}

.admin-table td {
  padding: var(--space-3);
  border-bottom: 1px solid var(--border-subtle);
  vertical-align: middle;
}

.admin-table tr:last-child td { border-bottom: none; }
.admin-table tr:hover td { background-color: var(--color-white-05); }

.membership-house-name { color: var(--house-color); }

.admin-table__actions {
  display: flex;
  gap: var(--space-2);
  justify-content: flex-end;
}

/* ── Filter bar ─────────────────────────────────── */

.filter-bar {
  display: flex;
  gap: var(--space-2);
  margin-bottom: var(--space-5);
  flex-wrap: wrap;
  align-items: center;
}

.filter-bar__input,
.filter-bar__select {
  height: 32px;
  width: auto;
  flex: 1;
  min-width: 140px;
  font-size: var(--text-sm);
}

/* ── Archived state ─────────────────────────────── */

.season-archived,
.archived-container {
  filter: saturate(0.35);
  position: relative;
}

.archived-label {
  position: absolute;
  top: var(--space-2);
  right: var(--space-2);
  font-size: var(--text-xs);
  color: var(--color-ash);
  letter-spacing: var(--tracking-wider);
  pointer-events: none;
  text-transform: uppercase;
}

/* ── Keyframes ──────────────────────────────────── */

@keyframes pulse-online {
  0%, 100% { box-shadow: 0 0 0 0 rgba(74, 222, 128, 0.4); }
  70%       { box-shadow: 0 0 0 6px rgba(74, 222, 128, 0); }
}

@keyframes slide-in-right {
  from { transform: translateX(12px); opacity: 0; }
  to   { transform: translateX(0);    opacity: 1; }
}

@keyframes badge-pop {
  0%   { transform: scale(0.7); opacity: 0; }
  60%  { transform: scale(1.12); }
  100% { transform: scale(1); opacity: 1; }
}

@keyframes fade-up {
  from { transform: translateY(6px); opacity: 0; }
  to   { transform: translateY(0);   opacity: 1; }
}

@keyframes vine-draw {
  from { stroke-dashoffset: 600; }
  to   { stroke-dashoffset: 0; }
}

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