/* Photo Studio - base design system. Shared by every page in the app. */

:root {
  --bg-body: #0f172a;
  --bg-card: #1e293b;
  --bg-input: #0f172a;
  --border-card: #334155;
  --border-input: #334155;
  --text-bright: #f8fafc;
  --text-heading: #f1f5f9;
  --text-primary: #e2e8f0;
  --text-secondary: #94a3b8;
  --text-muted: #64748b;
  --accent-blue: #60a5fa;
  /* Darkened from the original #3b82f6 (axe-core: color-contrast, serious -
     white text on #3b82f6 measured ~3.5:1, below the 4.5:1 AA minimum for
     normal-weight text; #2563eb measures ~4.9:1 with --text-bright). Still
     used for the "selected" tile indicator (app.css), a non-text element
     WCAG's text-contrast rule does not apply to. */
  --accent-blue-dark: #2563eb;
  /* .btn-primary:hover only - darkening on hover (rather than the previous
     lighter --accent-blue, which drops white-text contrast to ~2.4:1) keeps
     the hover state AA-compliant too, even though axe never evaluates a
     :hover state directly. */
  --accent-blue-darker: #1d4ed8;
  --accent-indigo: #6366f1;
  --color-success: #4ade80;
  --color-warning: #fbbf24;
  --color-danger: #f87171;
  --color-info: #38bdf8;
  --print-bg: #ffffff;
  --print-text: #000000;

  --space-xs: 4px;
  --space-sm: 8px;
  --space-md: 16px;
  --space-lg: 24px;
  --space-xl: 32px;
  --space-2xl: 48px;

  --card-radius: 12px;
  --input-radius: 8px;

  --transition-fast: 0.15s ease;
  --transition-normal: 0.2s ease;
  --transition-slow: 0.3s ease;

  --container-max: 1200px;

  --font-sans: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  --font-mono: 'JetBrains Mono', 'Fira Code', 'Consolas', monospace;
}

/* Reset */

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

html,
body {
  margin: 0;
  padding: 0;
}

body {
  background: var(--bg-body);
  color: var(--text-primary);
  font-family: var(--font-sans);
  font-size: 15px;
  line-height: 1.5;
}

h1,
h2,
h3,
h4,
h5,
h6 {
  margin: 0 0 var(--space-md) 0;
  color: var(--text-heading);
  font-weight: 600;
  line-height: 1.25;
}

p {
  margin: 0 0 var(--space-md) 0;
}

a {
  color: var(--accent-blue);
  text-decoration: none;
}

a:hover {
  text-decoration: underline;
}

/* axe-core: link-in-text-block (serious) - an inline link inside a prose
   paragraph (docs.html) must be distinguishable from surrounding text by
   more than colour alone. Scoped to "p a" only, so nav links, card links,
   and the photo grid's "Edit" link (none of them sit inside a <p>) keep
   their existing colour-only, underline-on-hover treatment. */
p a {
  text-decoration: underline;
}

ul,
ol {
  margin: 0;
  padding: 0;
}

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

button {
  font-family: inherit;
}

/* Layout */

.container {
  max-width: var(--container-max);
  margin: 0 auto;
  padding: var(--space-lg);
}

.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: var(--space-lg);
}

.split-panels {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-lg);
}

/* Nav bar */

.navbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-md);
  padding: var(--space-md) var(--space-lg);
  background: var(--bg-card);
  border-bottom: 1px solid var(--border-card);
}

.navbar-brand {
  color: var(--text-bright);
  font-weight: 600;
  font-size: 1.1em;
}

.navbar-brand:hover {
  text-decoration: none;
}

.navbar-links {
  display: flex;
  align-items: center;
  gap: var(--space-md);
  list-style: none;
}

.navbar-link {
  color: var(--text-secondary);
  padding: var(--space-xs) var(--space-sm);
  border-radius: var(--input-radius);
  transition: color var(--transition-fast), background var(--transition-fast);
}

.navbar-link:hover {
  color: var(--text-bright);
  background: var(--bg-body);
  text-decoration: none;
}

.navbar-link.active {
  color: var(--text-bright);
  background: var(--bg-body);
}

/* Buttons */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-xs);
  padding: var(--space-sm) var(--space-md);
  border: 1px solid var(--border-card);
  border-radius: var(--input-radius);
  background: var(--bg-card);
  color: var(--text-primary);
  font-size: 0.95em;
  font-weight: 500;
  cursor: pointer;
  transition: background var(--transition-fast), border-color var(--transition-fast),
    opacity var(--transition-fast);
}

.btn:hover {
  border-color: var(--accent-blue);
}

.btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.btn-primary {
  background: var(--accent-blue-dark);
  border-color: var(--accent-blue-dark);
  color: var(--text-bright);
}

.btn-primary:hover {
  background: var(--accent-blue-darker);
  border-color: var(--accent-blue-darker);
}

.btn-danger {
  background: transparent;
  border-color: var(--color-danger);
  color: var(--color-danger);
}

.btn-danger:hover {
  background: var(--color-danger);
  color: var(--text-bright);
}

.btn-sm {
  padding: var(--space-xs) var(--space-sm);
  font-size: 0.85em;
}

/* Forms */

.form-group {
  margin-bottom: var(--space-md);
}

.form-label {
  display: block;
  margin-bottom: var(--space-xs);
  color: var(--text-secondary);
  font-size: 0.9em;
  font-weight: 500;
}

.form-input,
.form-select,
.form-textarea {
  width: 100%;
  padding: var(--space-sm) var(--space-md);
  background: var(--bg-input);
  border: 1px solid var(--border-input);
  border-radius: var(--input-radius);
  color: var(--text-primary);
  font-family: inherit;
  font-size: 1em;
  transition: border-color var(--transition-fast);
}

.form-input:focus,
.form-select:focus,
.form-textarea:focus {
  outline: none;
  border-color: var(--accent-blue);
}

.form-textarea {
  resize: vertical;
  min-height: 6em;
}

/* Range sliders (mentor pass Fix 1). There was no styling for
   input[type=range] anywhere in this app before - every slider (12 on the
   editor page, 14 on presets) rendered as the bare browser default, bright
   blue on every platform, which reads louder than the photograph the
   sliders are meant to be grading. --range-fill is a 0-100% custom
   property kept in sync with each slider's actual value by
   util.js's updateRangeFill/initRangeFills (same "JS sets a custom
   property" pattern this app already uses for the compare slider's
   --reveal and the job progress bar's --progress), so the coloured portion
   of the track always tracks the thumb rather than staying fixed at 50%. */
input[type="range"] {
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  height: 20px;
  margin: 0;
  padding: 0;
  background: transparent;
  cursor: pointer;
  --range-fill: 50%;
}

input[type="range"]::-webkit-slider-runnable-track {
  height: 4px;
  border-radius: 2px;
  /* --accent-blue up to the thumb, --border-input beyond it - a muted,
     low-contrast pairing on purpose (this sits behind the photo it is
     grading, not competing with it). */
  background: linear-gradient(
    to right,
    var(--accent-blue) var(--range-fill),
    var(--border-input) var(--range-fill));
}

input[type="range"]::-moz-range-track {
  height: 4px;
  border-radius: 2px;
  background: var(--border-input);
}

input[type="range"]::-moz-range-progress {
  height: 4px;
  border-radius: 2px;
  background: var(--accent-blue);
}

input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: var(--accent-blue);
  border: 2px solid var(--bg-body);
  /* (track height - thumb height) / 2 = (4 - 16) / 2 - the standard offset
     needed to centre a WebKit thumb vertically on its own track. */
  margin-top: -6px;
  transition: background var(--transition-fast), transform var(--transition-fast),
    box-shadow var(--transition-fast);
}

input[type="range"]::-moz-range-thumb {
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: var(--accent-blue);
  border: 2px solid var(--bg-body);
  transition: background var(--transition-fast), transform var(--transition-fast),
    box-shadow var(--transition-fast);
}

input[type="range"]:hover::-webkit-slider-thumb {
  background: var(--accent-blue-dark);
  transform: scale(1.15);
}

input[type="range"]:hover::-moz-range-thumb {
  background: var(--accent-blue-dark);
  transform: scale(1.15);
}

/* Keyboard focus ring - never removed without a replacement (WCAG 2.4.7).
   Applied to the thumb itself (not the input's own box) since that is the
   part of the control a sighted keyboard user is actually tracking. */
input[type="range"]:focus-visible {
  outline: none;
}

input[type="range"]:focus-visible::-webkit-slider-thumb {
  background: var(--accent-blue-dark);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--accent-blue) 40%, transparent);
}

input[type="range"]:focus-visible::-moz-range-thumb {
  background: var(--accent-blue-dark);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--accent-blue) 40%, transparent);
}

input[type="range"]:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

@media (max-width: 768px) {
  /* Effective touch target: the visible track/thumb stay small and
     precise, but the control ROW gets extra vertical padding on touch-
     sized viewports so the actual hit area is comfortably >= 44px tall,
     per the brief's own guidance ("via padding on the control row"). */
  .slider-row {
    padding-block: var(--space-sm);
  }

  input[type="range"] {
    height: 28px;
  }
}

/* File inputs (mentor pass Fix 2). The native "Choose File" control (a
   white system button on this dark theme) is replaced everywhere with a
   visually hidden input plus a <label for="..."> styled as a .btn - the
   label's click opens the native file picker exactly like clicking the
   input would, so no behaviour changes, only the chrome. Standard
   accessible-hidden-input technique: NOT display:none (that would drop it
   from the tab order and break the label's own focus-visible hook below),
   just clipped to a single pixel and off the visible layout. */
.file-input-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.file-input-row {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  flex-wrap: wrap;
}

.file-input-btn {
  cursor: pointer;
}

/* Visible keyboard focus ring on the label whenever the (visually hidden,
   but still real and still tabbable) input it is bound to has focus - a
   label has no focus of its own to show a ring on otherwise. */
.file-input-hidden:focus-visible + .file-input-btn {
  outline: 2px solid var(--accent-blue);
  outline-offset: 2px;
}

.file-input-filename {
  margin-top: 0;
  color: var(--text-secondary);
}

.error-text {
  color: var(--color-danger);
  font-size: 0.9em;
  margin-top: var(--space-xs);
}

.help-text {
  color: var(--text-secondary);
  font-size: 0.85em;
  margin-top: var(--space-xs);
}

/* Cards */

.card {
  background: var(--bg-card);
  border: 1px solid var(--border-card);
  border-radius: var(--card-radius);
  padding: var(--space-lg);
}

.card-title {
  color: var(--text-heading);
  font-weight: 600;
  margin-bottom: var(--space-sm);
}

/* Tables */

.table {
  width: 100%;
  border-collapse: collapse;
}

.table th,
.table td {
  text-align: left;
  padding: var(--space-sm) var(--space-md);
  border-bottom: 1px solid var(--border-card);
}

.table th {
  color: var(--text-secondary);
  font-weight: 500;
  font-size: 0.85em;
  text-transform: uppercase;
  letter-spacing: 0.03em;
}

.table tbody tr:hover {
  background: rgba(255, 255, 255, 0.02);
}

/* Badges */

.badge {
  display: inline-flex;
  align-items: center;
  padding: var(--space-xs) var(--space-sm);
  border-radius: var(--input-radius);
  font-size: 0.8em;
  font-weight: 600;
  line-height: 1.2;
}

.badge-success {
  background: color-mix(in srgb, var(--color-success) 15%, transparent);
  color: var(--color-success);
}

.badge-warning {
  background: color-mix(in srgb, var(--color-warning) 15%, transparent);
  color: var(--color-warning);
}

.badge-danger {
  background: color-mix(in srgb, var(--color-danger) 15%, transparent);
  color: var(--color-danger);
}

.badge-info {
  background: color-mix(in srgb, var(--color-info) 15%, transparent);
  color: var(--color-info);
}

/* Toast */

#toast-host {
  position: fixed;
  top: var(--space-lg);
  right: var(--space-lg);
  z-index: 1000;
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
}

.toast {
  min-width: 240px;
  max-width: 360px;
  padding: var(--space-sm) var(--space-md);
  background: var(--bg-card);
  border: 1px solid var(--border-card);
  border-left: 3px solid var(--accent-blue);
  border-radius: var(--input-radius);
  color: var(--text-primary);
  font-size: 0.9em;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
  animation: toast-in var(--transition-normal);
}

.toast-success {
  border-left-color: var(--color-success);
}

.toast-error {
  border-left-color: var(--color-danger);
}

.toast-info {
  border-left-color: var(--color-info);
}

@keyframes toast-in {
  from {
    opacity: 0;
    transform: translateY(-8px);
  }

  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* Modal */

.modal-backdrop {
  position: fixed;
  inset: 0;
  z-index: 1100;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, 0.6);
}

.modal {
  width: 90%;
  max-width: 420px;
  background: var(--bg-card);
  border: 1px solid var(--border-card);
  border-radius: var(--card-radius);
  padding: var(--space-lg);
}

.modal-message {
  color: var(--text-primary);
  margin-bottom: var(--space-lg);
}

.modal-actions {
  display: flex;
  justify-content: flex-end;
  gap: var(--space-sm);
}

/* Spinner */

.spinner {
  width: 24px;
  height: 24px;
  border: 3px solid var(--border-card);
  border-top-color: var(--accent-blue);
  border-radius: 50%;
  animation: spinner-spin 0.8s linear infinite;
}

@keyframes spinner-spin {
  to {
    transform: rotate(360deg);
  }
}

/* Empty state */

.empty-state {
  text-align: center;
  padding: var(--space-2xl) var(--space-lg);
  color: var(--text-secondary);
}

.empty-state-title {
  color: var(--text-heading);
  margin-bottom: var(--space-sm);
}

/* Login card (used by static/login.html) */

.login-wrap {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
}

.login-card {
  width: 100%;
  max-width: 360px;
}

/* Responsive */

@media (max-width: 768px) {
  .card-grid {
    grid-template-columns: 1fr;
  }

  .split-panels {
    grid-template-columns: 1fr;
  }

  .navbar {
    flex-wrap: wrap;
  }
}

/* Print */

@media print {
  .navbar,
  .btn,
  #toast-host,
  .modal-backdrop {
    display: none;
  }

  body {
    background: var(--print-bg);
    color: var(--print-text);
  }
}
