/* ═══════════════════════════════════════════════════════════════════════
   FORM FIELDS — one appearance everywhere
   ───────────────────────────────────────────────────────────────────────
   The sign-in modal's field (.finp) is the reference. The site had grown
   a dozen variants besides it — .pf-input, .form-input, .admin-select,
   .qr-control, .q-type, .opt-text and others, plus eleven fields styled
   inline in the admin screens — so the same form control looked different
   depending on which page you were on.

   This file sets the *box*: background, border, radius, colour and focus
   state. It deliberately does not set font-size, letter-spacing or
   text-align, so fields that are meant to look different still do — the
   six-digit OTP box keeps its wide tracking, it just now sits in the same
   shell as everything else.

   Loaded last so it wins on order. !important appears only on the
   properties the inline admin styles also set; everything else is a plain
   default that a component rule can still override.
   ═══════════════════════════════════════════════════════════════════════ */

/* Everything a person types into. Checkboxes, radios, file pickers, colour
   swatches, range sliders and buttons are excluded — they are native
   controls with their own shapes, and restyling them here would break them. */
input:not([type="checkbox"]):not([type="radio"]):not([type="file"]):not([type="range"]):not([type="color"]):not([type="submit"]):not([type="button"]):not([type="reset"]):not([type="image"]),
select,
textarea {
  background: rgba(0, 0, 0, 0.3) !important;
  border: 1px solid var(--bdr) !important;
  border-radius: 8px !important;
  color: var(--t) !important;
  outline: none;
  transition: border-color 0.2s ease, background 0.2s ease, box-shadow 0.2s ease;
}

/* Plain defaults, not !important: a component that wants its own spacing or
   width still gets it. These only reach fields that set nothing of their own. */
input:not([type="checkbox"]):not([type="radio"]):not([type="file"]):not([type="range"]):not([type="color"]):not([type="submit"]):not([type="button"]):not([type="reset"]):not([type="image"]),
select,
textarea {
  padding: 10px 14px;
  font-family: 'Exo 2', 'Inter', sans-serif;
  font-size: 0.88rem;
  width: 100%;
  max-width: 100%;
  box-sizing: border-box;
}

input:not([type="checkbox"]):not([type="radio"]):not([type="file"]):not([type="range"]):not([type="color"]):not([type="submit"]):not([type="button"]):not([type="reset"]):not([type="image"]):focus,
select:focus,
textarea:focus {
  border-color: var(--c) !important;
  background: rgba(0, 212, 255, 0.03) !important;
  box-shadow: 0 0 0 2px rgba(0, 212, 255, 0.08) !important;
}

input::placeholder,
textarea::placeholder { color: var(--tm); opacity: 1; }

/* Disabled and read-only read as "not for you" without looking broken. */
input:disabled, select:disabled, textarea:disabled,
input[readonly], textarea[readonly] {
  opacity: 0.6;
  cursor: not-allowed;
}

textarea { min-height: 120px; resize: vertical; }

/* The native dropdown list is drawn by the OS and inherits nothing, so its
   options need a surface of their own or they render white-on-white. */
select option { background: var(--bg3); color: var(--t); }

/* Invalid state, for fields a server round-trip has rejected. */
input.is-invalid, select.is-invalid, textarea.is-invalid {
  border-color: rgba(255, 80, 80, 0.65) !important;
}

/* ── Light theme ──────────────────────────────────────────────────────
   The dark field is a translucent black, which on a near-white page is a
   grey smear. Light mode gets a real white field instead. */
[data-theme="light"] input:not([type="checkbox"]):not([type="radio"]):not([type="file"]):not([type="range"]):not([type="color"]):not([type="submit"]):not([type="button"]):not([type="reset"]):not([type="image"]),
[data-theme="light"] select,
[data-theme="light"] textarea {
  background: #ffffff !important;
  border-color: rgba(0, 0, 0, 0.14) !important;
  color: #1e293b !important;
}

[data-theme="light"] input:not([type="checkbox"]):not([type="radio"]):not([type="file"]):not([type="range"]):not([type="color"]):not([type="submit"]):not([type="button"]):not([type="reset"]):not([type="image"]):focus,
[data-theme="light"] select:focus,
[data-theme="light"] textarea:focus {
  border-color: #0062cc !important;
  background: #ffffff !important;
  box-shadow: 0 0 0 3px rgba(0, 98, 204, 0.12) !important;
}

[data-theme="light"] input::placeholder,
[data-theme="light"] textarea::placeholder { color: #64748b; }
[data-theme="light"] select option { background: #ffffff; color: #1e293b; }

/* Search fields sit inside a wrapper that draws its own icon, so they keep
   their own width rather than stretching to the full row. */
.adm-search, .search-input { width: 100%; }

@media (prefers-reduced-motion: reduce) {
  input, select, textarea { transition: none; }
}

/* ═══════════════════════════════════════════════════════════════════════
   PANEL ACCENT — the gradient strip from the sign-in card
   ───────────────────────────────────────────────────────────────────────
   .modal-box drew a cyan-to-orange line across its top edge; every other
   panel was a plain bordered box, so the sign-in card looked like a
   different product. This puts the same edge on every card that holds a
   form, the sign-in card included.

   The strip is a full-size layer shaped to the card (border-radius:
   inherit) with only its top band painted, rather than a short bar with
   its own radius. A 3px-tall box cannot render a 16px corner, so the old
   approach stayed square and overhung the curve. This follows whatever
   radius each card actually has.

   Masked rather than clipped with overflow:hidden, because several of
   these cards hold tables, menus and hover lift that must not be clipped.

   Deliberately NOT applied to:
     .cj-card    — the certification tiers carry their own per-tier colour
     .tcard      — has .tcard-accent, its own coloured rule
     .course-card / .ccard — artwork sits flush at the top edge
     .dash-panel      — a tab show/hide container, not a card: the accent
                        drew a stray line across each admin page above its title
     .form-container  — a layout wrapper (max-width + margin auto, no surface
                        of its own), used twice per page on the create/edit
                        screens, so it drew two stray lines. The real card on
                        those pages is .form-card, which is covered.
     .dash-card       — not defined anywhere in the CSS; removed as dead weight

   The rule for inclusion: the selector must name an element that actually
   draws a surface — background, border and radius. A wrapper that only
   positions its children gets a line across open space instead of an edge.
   ═══════════════════════════════════════════════════════════════════════ */

.modal-box,
.pf-card,
.forgot-card,
.reset-card,
.lk-card,
.rc-box,
.form-card,
.qr-card,
.contact-section,
.admin-card,
.ts-card {
  position: relative;
}

.modal-box::before,
.pf-card::before,
.forgot-card::before,
.reset-card::before,
.lk-card::before,
.rc-box::before,
.form-card::before,
.qr-card::before,
.contact-section::before,
.admin-card::before,
.ts-card::before {
  content: '';
  position: absolute;
  inset: 0;
  /* height:auto is needed to beat the original .modal-box::before rule in
     style.css, which pins it to 2px. */
  height: auto;
  border-radius: inherit;
  background: linear-gradient(90deg, var(--c), var(--o));
  -webkit-mask-image: linear-gradient(#000 0 3px, transparent 3px);
          mask-image: linear-gradient(#000 0 3px, transparent 3px);
  pointer-events: none;
  z-index: 0;
}

/* The accent layer sits above the card's background but below its content,
   so nothing it covers becomes unreadable or unclickable. */
.modal-box > *,
.pf-card > *,
.forgot-card > *,
.reset-card > *,
.form-card > *,
.qr-card > *,
.contact-section > * {
  position: relative;
  z-index: 1;
}

/* ═══════════════════════════════════════════════════════════════════════
   LIGHT-MODE CORRECTIONS
   ───────────────────────────────────────────────────────────────────────
   Two elements were coloured for the dark theme only and fail on a white
   ground. Both are scoped to [data-theme="light"], so dark mode is
   untouched.
   ═══════════════════════════════════════════════════════════════════════ */

/* The theme toggle's sun was #ffd700 — gold on white is roughly 1.4:1, so
   the icon read as a yellow smudge rather than a shape. A deeper amber
   keeps it recognisably a sun while actually being legible. */
[data-theme="light"] #theme-toggle .fa-sun { color: #b45309 !important; }
[data-theme="light"] #theme-toggle {
  border-color: rgba(13, 39, 77, 0.16);
  background: #ffffff;
}
[data-theme="light"] #theme-toggle:hover {
  border-color: #0062cc;
  background: #f1f6fb;
}

/* The course artwork is a watermark behind the hero text, faded to 25%.
   That works on the dark hero because the art's own navy backdrop matches
   it. On a pale hero the same backdrop turns into a grey smear, so light
   mode inverts it first: the navy plate becomes a near-white that melts
   into the hero, and hue-rotate puts the cyan linework back to cyan after
   the inversion flipped it to orange. Same faded watermark, correct ground.

   Geometry is left exactly as dark mode has it — only the colour changes. */
[data-theme="light"] .course-hero-image {
  filter: invert(1) hue-rotate(180deg);
  opacity: 0.30;
}

/* ═══════════════════════════════════════════════════════════════════════
   BUTTON GLOW — removed
   ───────────────────────────────────────────────────────────────────────
   style.css gives the primary buttons an all-round cyan halo on hover
   (.btn-c at 25px, .btn-primary at 20px, .btn-ghost at 15px), and
   premium-animations.css adds another on .btn/.nbtn/button. Those are
   spread-only shadows with no offset, so they read as the button lighting
   up rather than lifting.

   The lift stays; only the glow goes. !important is needed because the
   originals are in sheets that load before this one at equal specificity,
   and the mobile sheet marks its own as !important.
   ═══════════════════════════════════════════════════════════════════════ */

.btn-c:hover,
.btn-primary:hover,
.btn-ghost:hover,
.nbtn:hover,
.lhbtn:hover,
.lhbtn-cta:hover,
.lhbtn-ghost:hover,
.hbtn:hover,
.form-submit:hover,
.nav-btn:hover,
button:hover,
.btn:hover {
  box-shadow: none !important;
}


/* ── Skip link ──────────────────────────────────────────────────────────
   Hidden off-screen until it takes focus, then pinned to the top-left
   above everything - including the sticky header, which must not cover
   the element the user just focused. */
.skip-link {
  position: fixed; top: 0; left: -9999px;
  z-index: 100000;
  background: var(--c, #00d4ff); color: #00131c;
  padding: 0.75rem 1.25rem;
  border-radius: 0 0 10px 0;
  font-weight: 700; font-size: 0.9rem; text-decoration: none;
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.35);
}
.skip-link:focus { left: 0; outline: 2px solid #fff; outline-offset: -4px; }
[data-theme="light"] .skip-link { background: #0062cc; color: #fff; }

/* ── Native control theming ─────────────────────────────────────────────
   The layout ships <meta name="color-scheme" content="dark">, which is
   static. Declaring it here instead lets it follow the theme toggle, so
   scrollbars, date pickers and native <select> popups match the page in
   light mode too rather than staying dark. */
:root { color-scheme: dark; }
[data-theme="light"] { color-scheme: light; }
