/* WanderPlan base rules — v1
 *
 * Load AFTER tokens.css. These are the rules that fix the systemic gaps
 * (focus, double-submit, hit areas, status rings) globally, before any
 * individual component is touched. Ship this second; it is the highest
 * ratio of problems-solved to templates-edited in the whole system.
 */

/* ---- 0 · Base ------------------------------------------------------ */
html { -webkit-text-size-adjust: 100%; }

body {
  font-family: var(--wp-font-sans);
  font-size: var(--wp-text-body);
  line-height: var(--wp-lh-body);
  color: var(--wp-ink);
  background: var(--wp-canvas);
  -webkit-font-smoothing: antialiased;
  text-wrap: pretty;
}

a { color: var(--wp-ink); text-decoration: underline; text-underline-offset: 2px; text-decoration-thickness: 1px; }
a:hover { text-decoration-thickness: 2px; }

/* There is no brand hue. Every hue is spoken for — parties own the
   categorical range, status owns green/amber/red. Emphasis is carried by
   weight and contrast, so the primary action is ink. */

/* ---- 1 · Status rings ---------------------------------------------
   outline, not border: outline supports dashed and does not affect
   layout. outline-offset keeps the ring inside the card box. */
.wp-ring-ok    { outline: 2px solid var(--wp-status-ok);    outline-offset: -2px; }
.wp-ring-warn  { outline: 2px dashed var(--wp-status-warn); outline-offset: -2px; }
.wp-ring-error { outline: 2px solid var(--wp-status-error); outline-offset: -2px; }
.wp-ring-idea  { outline: 1.5px solid var(--wp-status-idea-ring); outline-offset: -2px;
                 opacity: var(--wp-status-idea-opacity); }

html[data-theme="dark"] .wp-ring-ok,
html[data-theme="dark"] .wp-ring-warn,
html[data-theme="dark"] .wp-ring-error { outline-width: 2.5px; }

/* ---- 2 · Focus is a shape, not a colour ---------------------------
   Two rings — ink plus a surface-coloured halo — so it survives on any
   background, in dark mode, and for every colour-vision deficiency.
   No hue is consumed. */
:focus-visible {
  outline: 2px solid var(--wp-ink);
  outline-offset: 2px;
  box-shadow: 0 0 0 4px var(--wp-raised);
}
:focus:not(:focus-visible) { outline: none; }

/* ---- 3 · Every mutating control is guarded -------------------------
   Pair with hx-disabled-elt="this" on the trigger. Between them these
   remove the double-submit hole and give ~190 interactive attributes a
   loading state for free. */
.htmx-request { opacity: 0.6; pointer-events: none; cursor: wait; }
.htmx-indicator { display: none; }
.htmx-request .htmx-indicator,
.htmx-request.htmx-indicator { display: inline-flex; }

[disabled], [aria-disabled="true"] {
  background: var(--wp-sunken);
  color: var(--wp-n-500);
  border-color: var(--wp-rule);
  cursor: not-allowed;
}
/* Never pointer-events:none on a disabled control — it also removes the
   tooltip that explains why it is disabled. */

@keyframes wp-spin { to { transform: rotate(360deg); } }
.wp-spinner {
  width: 1em; height: 1em; border-radius: 50%;
  border: 2px solid currentColor; border-top-color: transparent;
  animation: wp-spin 0.7s linear infinite;
}

@keyframes wp-pulse { 0%, 100% { opacity: 0.35; } 50% { opacity: 0.9; } }
.wp-skeleton { border-radius: var(--wp-radius-sm); background: var(--wp-rule);
               animation: wp-pulse 1.4s ease-in-out infinite; }

/* ---- 4 · Hit areas -------------------------------------------------
   The glyph stays 18–20px. The target never drops below 44px, on desktop
   too — board icon buttons sit 4px apart and a mouse is not that accurate
   either. */
button, [role="button"], a.wp-btn, [tabindex="0"].wp-editable {
  min-height: var(--wp-control-h);
}
.wp-icon-btn {
  min-width: var(--wp-hit-min);
  min-height: var(--wp-hit-min);
  display: inline-flex; align-items: center; justify-content: center;
}
@media (pointer: coarse) {
  button, [role="button"], a.wp-btn { min-height: var(--wp-control-h-touch); }
  .wp-icon-btn { min-width: 48px; min-height: 48px; }
}

/* ---- 5 · Anything machine-ish is mono and tabular ------------------ */
.wp-num {
  font-family: var(--wp-font-mono);
  font-variant-numeric: tabular-nums;
  font-size: var(--wp-text-meta);
  color: var(--wp-muted);
}

/* ---- Type utilities ------------------------------------------------ */
.wp-hero    { font-size: var(--wp-text-hero);    line-height: var(--wp-lh-hero);    letter-spacing: var(--wp-track-hero);    font-weight: 700; }
.wp-page    { font-size: var(--wp-text-page);    line-height: var(--wp-lh-page);    letter-spacing: var(--wp-track-page);    font-weight: 700; }
.wp-section { font-size: var(--wp-text-section); line-height: var(--wp-lh-section); letter-spacing: var(--wp-track-section); font-weight: 600; }
.wp-title   { font-size: var(--wp-text-title);   line-height: var(--wp-lh-title);   letter-spacing: var(--wp-track-title);   font-weight: 600; }
.wp-body    { font-size: var(--wp-text-body);    line-height: var(--wp-lh-body); }
.wp-meta    { font-size: var(--wp-text-meta);    line-height: var(--wp-lh-meta);    font-family: var(--wp-font-mono); color: var(--wp-muted); }
.wp-micro   { font-size: var(--wp-text-micro);   line-height: var(--wp-lh-micro);   letter-spacing: var(--wp-track-micro);
              font-weight: 600; text-transform: uppercase; color: var(--wp-muted); }

/* ---- Click-to-edit ------------------------------------------------
   The display state currently has no affordance and no keyboard path.
   Both are solved here: dotted underline at rest, pencil on hover,
   pencil ALWAYS on touch, and a real keyboard target.
   Markup: <span class="wp-editable" tabindex="0" role="button"
                 aria-label="Edit trip title"> … </span> */
.wp-editable {
  display: inline-flex; align-items: center; gap: var(--wp-space-2);
  padding: var(--wp-space-1) var(--wp-space-1-5);
  margin: calc(var(--wp-space-1) * -1) calc(var(--wp-space-1-5) * -1);
  border-radius: var(--wp-radius-md);
  border-bottom: 1px dashed var(--wp-n-400);
  cursor: text;
}
.wp-editable .wp-editable-pencil { opacity: 0; transition: opacity 120ms ease; }
.wp-editable:hover .wp-editable-pencil,
.wp-editable:focus-visible .wp-editable-pencil { opacity: 1; }
@media (pointer: coarse) {
  .wp-editable { border: 1px solid var(--wp-rule); border-radius: var(--wp-radius-md);
                 background: var(--wp-canvas); padding: var(--wp-space-3);
                 min-height: var(--wp-control-h-touch); width: 100%;
                 justify-content: space-between; }
  .wp-editable .wp-editable-pencil { opacity: 1; }
}

/* ---- Party badge ---------------------------------------------------
   Hue identifies the party; the TREATMENT carries presence, so a
   colour-blind reader gets both channels.
     present  filled
     arrives  filled + "+"
     leaves   outlined + "×"
     away     dashed outline, muted */
.wp-party {
  font-family: var(--wp-font-mono); font-size: var(--wp-text-micro); font-weight: 600;
  border-radius: var(--wp-radius-full); height: 22px; padding: 0 9px;
  display: inline-flex; align-items: center; gap: 2px;
  color: var(--wp-on-ink); background: var(--wp-party);
}
.wp-party--leaves { background: transparent; color: var(--wp-party); border: 1.5px solid var(--wp-party); }
.wp-party--away   { background: transparent; color: var(--wp-muted); border: 1.5px dashed var(--wp-n-400); }
@media (pointer: coarse) { .wp-party { height: 26px; font-size: 0.75rem; padding: 0 10px; } }

/* ---- Icons ---------------------------------------------------------
   Resolve by SIZE, never by preference:
     < 20px  → the activity type's DEFAULT glyph (7 shapes, learnable)
     ≥ 20px  → the sub-icon (where personality lives and is legible)
   Icons never carry status. No badge overlays, no filled/outlined swap
   for booked, no colour on the glyph. The ring owns status. */
.wp-icon { flex-shrink: 0; stroke: currentColor; fill: none;
           stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
