/*
 * Application styles — served via Propshaft (not Tailwind CLI).
 * Dark mode overrides use the .dark class on <html>.
 */

/* ── Light mode contrast ───────────────────────────────
   Moved to app/assets/tailwind/application.css (2026-10-06), where the whole
   slate text scale is darkened, not only slate-400. */

/* ── Dark mode ─────────────────────────────────────── */
/* Screen only (2026-10-08): printed from dark mode, a page still comes out
   light on paper, the run sheet included. */
@media screen {

/* Background */
.dark body                    { background-color: #0f172a !important; color: #e2e8f0 !important; }
.dark nav.bg-slate-900        { background-color: #020617 !important; }

/* Cards and surfaces */
.dark .bg-white               { background-color: #1e293b !important; }
.dark .bg-slate-50            { background-color: #0f172a !important; }
.dark .bg-slate-100           { background-color: #334155 !important; }
.dark .bg-slate-200           { background-color: #475569 !important; }

/* Borders */
.dark .border-slate-200       { border-color: #334155 !important; }
.dark .border-slate-300       { border-color: #475569 !important; }
.dark .border-slate-100       { border-color: #1e293b !important; }
.dark .divide-slate-100 > :not(:last-child) { border-color: #1e293b !important; }

/* Text — remap slate scale for dark mode.
   Lifted one step for contrast: the faint metadata (400) was #64748b (~2.9:1 on
   card bg #1e293b, fails WCAG AA); now #94a3b8 (~4.6:1). Tune here if needed. */
.dark .text-slate-900         { color: #f8fafc !important; }
.dark .text-slate-800         { color: #f1f5f9 !important; }
.dark .text-slate-700         { color: #e2e8f0 !important; }
.dark .text-slate-600         { color: #cbd5e1 !important; }
.dark .text-slate-500         { color: #cbd5e1 !important; }
.dark .text-slate-400         { color: #94a3b8 !important; }

/* Coloured text in dark mode: app/assets/tailwind/application.css (2026-10-06). */

/* Headings */
.dark h1, .dark h2, .dark h3  { color: #f1f5f9 !important; }
.dark .font-bold               { color: inherit; }
.dark .font-semibold           { color: inherit; }
.dark .font-medium             { color: inherit; }

/* Form inputs */
.dark input[type="text"],
.dark input[type="email"],
.dark input[type="number"],
.dark input[type="date"],
.dark input[type="datetime-local"],
.dark input[type="url"],
.dark input[type="search"],
.dark input[type="password"],
.dark input[type="file"],
.dark textarea,
.dark select {
  background-color: #1e293b !important;
  border-color: #475569 !important;
  color: #e2e8f0 !important;
}
.dark input::placeholder,
.dark textarea::placeholder   { color: #64748b !important; }
.dark input[type="checkbox"]  { background-color: #1e293b !important; border-color: #475569 !important; }

/* Colored badges — translucent on dark bg */
.dark .bg-emerald-100         { background-color: rgba(16, 185, 129, 0.2) !important; }
.dark .bg-emerald-50          { background-color: rgba(16, 185, 129, 0.15) !important; }
.dark .bg-amber-100           { background-color: rgba(245, 158, 11, 0.2) !important; }
.dark .bg-amber-50            { background-color: rgba(245, 158, 11, 0.1) !important; }
.dark .bg-red-100             { background-color: rgba(239, 68, 68, 0.2) !important; }
.dark .bg-red-50              { background-color: rgba(239, 68, 68, 0.1) !important; }
.dark .bg-purple-50           { background-color: rgba(168, 85, 247, 0.15) !important; }
.dark .bg-purple-100          { background-color: rgba(168, 85, 247, 0.2) !important; }
.dark .bg-blue-100            { background-color: rgba(59, 130, 246, 0.2) !important; }
.dark .bg-blue-50             { background-color: rgba(59, 130, 246, 0.15) !important; }
.dark .bg-sky-100             { background-color: rgba(56, 189, 248, 0.2) !important; }
.dark .bg-rose-100            { background-color: rgba(244, 63, 94, 0.2) !important; }

/* Accent borders */
.dark .border-emerald-200     { border-color: rgba(16, 185, 129, 0.3) !important; }
.dark .border-emerald-300     { border-color: rgba(16, 185, 129, 0.4) !important; }
.dark .border-amber-200       { border-color: rgba(245, 158, 11, 0.3) !important; }
.dark .border-amber-300       { border-color: rgba(245, 158, 11, 0.4) !important; }
.dark .border-red-200         { border-color: rgba(239, 68, 68, 0.3) !important; }
.dark .border-red-300         { border-color: rgba(239, 68, 68, 0.4) !important; }

/* Flash messages */
.dark .bg-emerald-50.border-emerald-200 { background-color: rgba(16, 185, 129, 0.15) !important; border-color: rgba(16, 185, 129, 0.3) !important; }
.dark .bg-red-50.border-red-200 { background-color: rgba(239, 68, 68, 0.1) !important; border-color: rgba(239, 68, 68, 0.3) !important; }

/* Hover states */
.dark .hover\:bg-slate-50:hover  { background-color: #334155 !important; }
.dark .hover\:bg-slate-100:hover { background-color: #475569 !important; }

/* Links in dark */
.dark a.text-red-600:hover { color: #fca5a5 !important; }

/* Focus rings */
.dark .focus\:ring-red-500:focus { --tw-ring-color: rgba(239, 68, 68, 0.5); }
.dark .focus\:border-red-500:focus { border-color: rgba(239, 68, 68, 0.5) !important; }

/* Scrollbar */
.dark ::-webkit-scrollbar       { width: 8px; }
.dark ::-webkit-scrollbar-track { background: #1e293b; }
.dark ::-webkit-scrollbar-thumb { background: #475569; border-radius: 4px; }
}

/* ── 11pt (~14.7px) minimum type size, sitewide ────────────────────────
   ROADMAP.md "Parked — not applied, ready on request"; owner asked for it
   2026-09-23. text-xs (12px) and text-sm (14px) — plus the handful of
   arbitrary text-[9px]/[10px]/[11px] uses — were the only sub-11pt text in
   the product. Floored to one size rather than kept apart, since 12px and
   14px are close enough that keeping them distinct bought little hierarchy
   for the loss of a legible floor. This intentionally flattens the xs/sm
   distinction (both render the same) and enlarges every badge/pill built on
   text-xs (badges_helper's DEFAULT_BADGE_CLASSES included) and every dense
   table's timestamp/meta text.
   !important is required: this stylesheet loads before the compiled
   tailwind.css (both are pulled in by stylesheet_link_tag :app) and before
   the inline data-font-size <style> block in the layout head, so a
   non-important rule here would lose to both.
   max(), not a flat px value, because !important also beats the display
   density options in that same block, which set the ROOT size per mode
   (compact 14px, normal 16px, large 18px). A flat 14.7px floored Compact
   correctly but SHRANK Large's text-sm from 17.1px to 14.7px, making the
   one accessibility affordance in the product worse for the person who
   turned it on. max(14.7px, 0.95rem) resolves per mode: compact 14.7px
   (floored, was 9.8px), normal 15.2px, large 17.1px (unchanged). No mode
   renders smaller than before and none falls under 11pt. Compact and
   normal still render these two classes identically; that is the cost of
   a floor and it is the intended one. */
.text-xs,
.text-sm,
.text-\[9px\],
.text-\[10px\],
.text-\[11px\] {
  font-size: max(14.7px, 0.95rem) !important;
}

/* ── Named themes (data-theme on <html>) ───────────────────────────────
   Roadmap "Next candidates" (owner ask 2026-09-19): beyond light/dark, a
   small set of named themes an organization picks in Settings, with a
   member override (theme_controller.js, localStorage "theme-override").
   Slate is today's look and needs no rules here — it's the absence of any
   override. Warm and High contrast are written as design tokens (CSS
   custom properties), not per-element overrides: a handful of tokens,
   remapped onto the small set of Tailwind classes the chrome is actually
   built from. --ai-accent (the organization's own accent color, already
   used for avatars/PDFs/emails) is set inline per-request in the layout
   head, and only takes effect under Warm — Slate stays byte-identical to
   the current look for every organization that hasn't touched Settings,
   and High contrast keeps its own fixed palette so an arbitrary accent
   color can never undermine the contrast guarantee that theme exists for.
   Combines with dark mode as an orthogonal axis (a theme can be light or
   dark), not a replacement for it. */
/* Screen only (owner, 2026-10-08: "we dont want to print the theme"):
   paper prints plain, whatever theme or mode is on screen. */
@media screen {

[data-theme="warm"] {
  --ai-bg: #fdf8f3;
  --ai-surface: #fffaf5;
  --ai-border: #ead9c7;
}
[data-theme="high_contrast"]:not(.dark) {
  --ai-bg: #ffffff;
  --ai-surface: #ffffff;
  --ai-border: #000000;
  --ai-text: #000000;
}
.dark[data-theme="high_contrast"] {
  --ai-bg: #000000;
  --ai-surface: #000000;
  --ai-border: #ffffff;
  --ai-text: #ffffff;
}

[data-theme="warm"] body,
[data-theme="high_contrast"] body { background-color: var(--ai-bg) !important; }
[data-theme="warm"] .bg-slate-50,
[data-theme="high_contrast"] .bg-slate-50 { background-color: var(--ai-bg) !important; }
[data-theme="warm"] .bg-white,
[data-theme="high_contrast"] .bg-white { background-color: var(--ai-surface) !important; }
[data-theme="warm"] .border-slate-200,
[data-theme="warm"] .border-slate-100,
[data-theme="warm"] .border-slate-300,
[data-theme="high_contrast"] .border-slate-200,
[data-theme="high_contrast"] .border-slate-100,
[data-theme="high_contrast"] .border-slate-300 { border-color: var(--ai-border) !important; }

/* High contrast: flatten every text shade to the guaranteed-contrast token
   (both light and dark) and thicken borders — the whole point of this
   theme is a contrast floor nothing else (including an org's own accent
   choice, deliberately not applied here) can undermine. */
[data-theme="high_contrast"]:not(.dark) .text-slate-900,
[data-theme="high_contrast"]:not(.dark) .text-slate-800,
[data-theme="high_contrast"]:not(.dark) .text-slate-700,
[data-theme="high_contrast"]:not(.dark) .text-slate-600,
[data-theme="high_contrast"]:not(.dark) .text-slate-500,
[data-theme="high_contrast"]:not(.dark) .text-slate-400,
[data-theme="high_contrast"]:not(.dark) .text-slate-300 { color: var(--ai-text) !important; }
.dark[data-theme="high_contrast"] .text-slate-400,
.dark[data-theme="high_contrast"] .text-slate-500,
.dark[data-theme="high_contrast"] .text-slate-600 { color: var(--ai-text) !important; }
[data-theme="high_contrast"] .border-slate-200,
[data-theme="high_contrast"] .border-slate-300,
[data-theme="high_contrast"] .border-slate-100 { border-width: 2px !important; }

/* Warm: the organization's own accent color (Settings -> Accent color)
   applied to the app's primary-action red, so a warm-themed org's buttons
   and links pick up its brand color instead of ActionItem's default red.
   Falls back to that same red when the org has never set one. */
[data-theme="warm"] .bg-red-600,
[data-theme="warm"] .hover\:bg-red-500:hover { background-color: var(--ai-accent, #dc2626) !important; color: var(--ai-accent-text, #ffffff) !important; }
/* As text on white the accent is darkened when it wouldn't read (a gold
   accent): --ai-accent-ink (AccentContrast.on_white). */
[data-theme="warm"] .text-red-600,
[data-theme="warm"] a.text-red-600:hover,
[data-theme="warm"] .hover\:text-red-600:hover,
[data-theme="warm"] .hover\:text-red-500:hover { color: var(--ai-accent-ink, #dc2626) !important; }
[data-theme="warm"] .border-red-600 { border-color: var(--ai-accent, #dc2626) !important; }
[data-theme="warm"] .focus\:ring-red-500:focus { --tw-ring-color: var(--ai-accent, #dc2626); }
[data-theme="warm"] .focus\:border-red-500:focus { border-color: var(--ai-accent, #dc2626) !important; }
}

/* ── Visible keyboard focus ────────────────────────────────────────────
   Tailwind's preflight removes the browser's default outline, and nothing
   in this app put one back, so a keyboard user had no idea where they
   were. :focus-visible only shows it for keyboard and assistive
   navigation, never for a mouse click, which is why it can be applied
   this broadly without changing how the app looks to a mouse user. */
:focus-visible {
  outline: 2px solid #dc2626;
  outline-offset: 2px;
  border-radius: 2px;
}
.dark :focus-visible,
[data-theme="high_contrast"] :focus-visible {
  outline-color: currentColor;
}

/* ── Respect a request for less motion ─────────────────────────────────
   Vestibular disorders are not rare, and the OS-level setting is the
   person telling us directly. Transitions are decorative here; the flash
   message's fade is not, so it is held visible instead of animated away. */
@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;
  }
  [style*="fadeOut"] {
    animation: none !important;
    opacity: 1 !important;
    visibility: visible !important;
  }
}
