/* =====================================================================
 * global.css — shared component layer
 * Loaded last on every main page (plan, library, cooking, upload,
 * upload-pdf), so this file is the single source of truth for the named
 * button system, close button, and the canonical form input. Per-page
 * CSS keeps its own :root and bespoke widgets; these rules only define
 * the shared, named components.
 * ===================================================================== */

/* ===== Design Tokens =====
 * Values mirror the per-page :root tokens so nothing shifts on pages
 * that already define them; pages without tokens (e.g. upload) inherit
 * these. */
:root {
  --primary-blue: #1b6fd8;
  --primary-blue-hover: #1662c1;
  --text-header: #083463;
  --danger: #d32f2f;
  --danger-hover: #b71c1c;
  --success: #28a745;
  --success-hover: #218838;

  --btn-radius: 10px;
  --btn-padding: 10px 20px;
  --control-radius: 10px;
  --focus-ring: 0 0 0 3px rgba(27, 111, 216, 0.3);
}

/* ===== Unified Button System =====
 * Variants are grouped with .btn so a bare `.btn-primary` (the existing
 * markup convention) renders correctly without also needing `.btn`. */
.btn,
.btn-primary,
.btn-secondary,
.btn-danger,
.btn-danger-soft,
.btn-success {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: var(--btn-padding);
  border: 1px solid transparent;
  border-radius: var(--btn-radius);
  font-family: inherit;
  font-size: 14px;
  font-weight: 700;
  line-height: 1.2;
  cursor: pointer;
  text-decoration: none;
  transition: all 0.2s ease;
}

.btn-primary {
  background-color: var(--primary-blue);
  color: #ffffff;
  border-color: var(--primary-blue);
}
.btn-primary:hover:not(:disabled) {
  background-color: var(--primary-blue-hover);
  border-color: var(--primary-blue-hover);
  transform: translateY(-1px);
}

.btn-secondary {
  background-color: #f3f8ff;
  color: var(--text-header);
  border-color: #d3e3f7;
}
.btn-secondary:hover:not(:disabled) {
  background-color: #e7f1ff;
  border-color: #b8d2f2;
}

.btn-danger {
  background-color: var(--danger);
  color: #ffffff;
  border-color: var(--danger);
}
.btn-danger:hover:not(:disabled) {
  background-color: var(--danger-hover);
  border-color: var(--danger-hover);
  transform: translateY(-1px);
}

.btn-success {
  background-color: var(--success);
  color: #ffffff;
  border-color: var(--success);
}
.btn-success:hover:not(:disabled) {
  background-color: var(--success-hover);
  border-color: var(--success-hover);
  transform: translateY(-1px);
}

/* Soft-red variant for "leave/remove" actions that are reversible-ish and
   shouldn't read as loud as a full .btn-danger delete. Same palette as
   account.html's .acct-btn-danger-soft, promoted to the shared system so any
   page can use it (not just account.html's own <style> block). */
.btn-danger-soft {
  background-color: rgba(211, 59, 59, 0.08);
  color: #c0392b;
  border-color: rgba(211, 59, 59, 0.25);
}
.btn-danger-soft:hover:not(:disabled) {
  background-color: rgba(211, 59, 59, 0.14);
}

/* Shared focus + disabled states for every variant */
.btn:focus-visible,
.btn-primary:focus-visible,
.btn-secondary:focus-visible,
.btn-danger:focus-visible,
.btn-danger-soft:focus-visible,
.btn-success:focus-visible {
  outline: none;
  box-shadow: var(--focus-ring);
}

.btn:disabled,
.btn-primary:disabled,
.btn-secondary:disabled,
.btn-danger:disabled,
.btn-danger-soft:disabled,
.btn-success:disabled {
  opacity: 0.55;
  cursor: not-allowed;
  transform: none;
  box-shadow: none;
}

/* ===== Unified Close Button (.btn-x) ===== */

.btn-x {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 10px 20px;
  background: #f3f8ff;
  color: #083463;
  border: 1px solid #d3e3f7;
  border-radius: 10px;
  font-size: 14px;
  font-weight: 700;
  cursor: pointer;
  flex-shrink: 0;
  transition: background 0.15s, border-color 0.15s;
}

.btn-x:hover {
  background: #e7f1ff;
  border-color: #b8d2f2;
}

/* Overlay variant: for close buttons on dark/image backgrounds (e.g. image preview thumbnails) */
.btn-x--overlay {
  background: rgba(10, 33, 61, 0.88);
  color: white;
  border: none;
  border-radius: 50%;
  padding: 0;
  width: 24px;
  height: 24px;
  font-size: 13px;
}

.btn-x--overlay:hover {
  background: rgba(8, 26, 49, 0.95);
  color: white;
}

/* ===== Canonical Form Input (.form-input) =====
 * Shared across pages so text fields share padding, radius, and focus
 * ring. Per-page bespoke inputs keep their own rules. */
.form-input {
  height: 2.65rem;
  padding: 0 0.82rem;
  border: 1.5px solid #d7e1ee;
  border-radius: var(--control-radius);
  background: #ffffff;
  color: #0f172a;
  font-size: 0.95rem;
  font-family: inherit;
  transition:
    border-color 0.15s ease,
    box-shadow 0.15s ease,
    background-color 0.15s ease;
}

.form-input:hover {
  border-color: #becdde;
}

.form-input:focus {
  outline: none;
  border-color: var(--primary-blue);
  box-shadow: var(--focus-ring);
}

/* iOS Safari renders input[type=date] as an internal inline-flex (value
   segments + calendar icon) and, as a flex item, its "automatic minimum
   size" should collapse to 0 once overflow is non-visible — but WebKit
   doesn't apply that rule to this replaced control, so the shadow content's
   intrinsic width wins over width/min-width/max-width regardless of what
   the container allows (a long-standing WebKit bug: search "safari
   input date ignores width"). min-width: 0 + -webkit-appearance: none is
   the documented workaround (it also drops iOS's native chrome so our own
   .form-input border/background show through instead). overflow: hidden
   is a backstop for whatever still doesn't shrink. Desktop browsers don't
   have this bug, so all of this is a no-op there. */
input[type="date"] {
  min-width: 0;
  max-width: 100%;
  -webkit-appearance: none;
  appearance: none;
  overflow: hidden;
}

/* ===== Unified Spinner (.spinner) =====
 * One spinner for the whole app: a two-color ring (brand blue + green) that
 * always spins at the same speed. Base size covers most inline/section
 * loaders; --sm/--lg scale it for compact spots (buttons, pills) and
 * full-page/modal loaders. Wrap it in .spinner-container to center it with
 * a caption underneath. */
.spinner {
  display: inline-block;
  width: 2.5rem;
  height: 2.5rem;
  border: 4px solid var(--primary-blue);
  border-top-color: #ffffff;
  border-radius: 50%;
  animation: spinner-spin 0.85s linear infinite;
  flex-shrink: 0;
  /* Promote to its own GPU layer so the rotation composites a cached
   * bitmap instead of repainting the anti-aliased circular border every
   * frame — without this, some Windows/Chromium setups render the
   * rotation as jagged, shattered lines instead of a smooth ring. */
  will-change: transform;
  backface-visibility: hidden;
}

.spinner--sm {
  width: 1.15rem;
  height: 1.15rem;
  border-width: 2px;
}

.spinner--lg {
  width: 3.5rem;
  height: 3.5rem;
  border-width: 5px;
}

/* Brand colors lose contrast on dark surfaces (pills, toasts, overlays) —
 * use a plain white ring there instead of the two-tone brand version. */
.spinner--on-dark {
  border-color: rgba(255, 255, 255, 0.3);
  border-top-color: #ffffff;
}

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

.spinner-container {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1rem;
  text-align: center;
  padding: 2.5rem 0;
}

.spinner-container p {
  margin: 0;
  font-size: 1rem;
  font-weight: 600;
  color: var(--muted, #6b7c93);
}

/* ===== Mobile hardening (iOS Safari / Chrome) =====
 * global.css is loaded last on plan, library, cooking, upload & discover,
 * so these guards apply site-wide on the app pages. */

/* Stop iOS from auto-inflating text on rotate / reflow. */
html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

/* iOS zooms the page when a focused field's font-size is under 16px.
 * Force every text-entry control to 16px at phone/tablet widths so tapping
 * a field never triggers that zoom. Scoped to touch widths and only text
 * controls, so the desktop look is untouched. !important is intentional:
 * it beats the many bespoke per-page input classes without editing each. */
@media (max-width: 768px) {
  input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="color"]),
  select,
  textarea {
    font-size: 16px !important;
  }
}
