/* ================================================================
   berliney · components
   ----------------------------------------------------------------
   Reusable pieces. Structure follows the berliney design system:
   a base class owns layout + states via custom properties; variants
   only override the properties. Consumes tokens.css exclusively.
   ================================================================ */

/* ── button ──
   Variants: .primary (solid ink, rose on hover)
             .secondary (outline)
             .link (text-only)
   States: :hover, :active, :focus-visible, :disabled.
   Context: add .on-dark when the button sits on ink/video. */

/* The fill lives on a ::before layer so the scratched-edge hover
   (SVG displacement filter #btn-scratch) frays only the shape — the
   label on top stays crisp. Pages that use .btn must include the
   #btn-scratch <svg> definition (see index.html). */

.btn {
  --btn-bg: var(--button-primary-bg-default);
  --btn-fg: var(--button-primary-text);
  --btn-border: transparent;
  --btn-bg-hover: var(--button-primary-bg-hover);
  --btn-fg-hover: var(--button-primary-text-hover);
  --btn-bg-pressed: var(--button-primary-bg-pressed);
  --btn-fg-pressed: var(--button-primary-text-hover);

  position: relative;
  z-index: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  font-family: var(--font-accent);
  font-weight: 400;
  font-size: var(--text-label);
  letter-spacing: var(--tracking-wider);
  text-transform: uppercase;
  text-decoration: none;
  padding: 13px 32px 11px;
  min-height: 44px; /* touch target */
  border: none;
  border-radius: var(--button-radius); /* focus ring follows the pill */
  background: transparent;
  color: var(--btn-fg);
  cursor: pointer;
  white-space: nowrap;
  user-select: none;
  transition:
    color var(--duration-base) var(--ease-out),
    transform var(--duration-slow) var(--ease-out);
}

.btn::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: var(--button-radius);
  background: var(--btn-bg);
  border: 1.5px solid var(--btn-border);
  transition:
    background var(--duration-base) var(--ease-out),
    border-color var(--duration-base) var(--ease-out);
}

/* .is-* classes mirror the real pseudo-states for specimen/demo use */

.btn:hover,
.btn.is-hover {
  color: var(--btn-fg-hover);
}

.btn:hover::before,
.btn.is-hover::before {
  background: var(--btn-bg-hover);
  border-color: var(--btn-border-hover, transparent);
  filter: url('#btn-scratch');
}

.btn:active,
.btn.is-pressed {
  color: var(--btn-fg-pressed);
}

.btn:active::before,
.btn.is-pressed::before {
  background: var(--btn-bg-pressed);
  filter: url('#btn-scratch');
}

@media (prefers-reduced-motion: no-preference) {
  .btn:not(.link):hover,
  .btn:not(.link).is-hover {
    transform: scale(1.025);
  }
}

.btn:focus-visible,
.btn.is-focus {
  outline: 2px solid var(--color-focus-ring);
  outline-offset: 3px;
}

.btn:disabled {
  cursor: not-allowed;
  pointer-events: none;
  color: var(--button-disabled-fg);
  transform: none;
}

.btn:disabled::before {
  background: var(--button-disabled-bg);
  border-color: var(--button-disabled-border);
  filter: none;
}

/* variant: secondary (outline) */
.btn.secondary {
  --btn-bg: transparent;
  --btn-fg: var(--button-secondary-fg);
  --btn-border: var(--button-secondary-border);
  --btn-bg-hover: var(--button-secondary-bg-hover);
  --btn-fg-hover: var(--button-secondary-fg-hover);
  --btn-border-hover: var(--button-secondary-border);
  --btn-bg-pressed: var(--button-secondary-bg-pressed);
  --btn-fg-pressed: var(--button-secondary-fg-hover);
}

.btn.secondary:disabled::before {
  background: transparent;
}

/* variant: link (text-only) */
.btn.link {
  --btn-bg: transparent;
  --btn-fg: var(--button-link-fg);
  --btn-bg-hover: transparent;
  --btn-fg-hover: var(--button-link-fg-hover);
  --btn-bg-pressed: transparent;
  --btn-fg-pressed: var(--button-link-fg-hover);
  padding: 4px 2px;
  min-height: 0;
  border-radius: var(--radius-medium); /* text links take a gently rounded ring, not the pill */
  text-decoration: underline;
  text-underline-offset: 4px;
  text-decoration-thickness: 1.5px;
}

.btn.link:disabled::before {
  background: transparent;
  border-color: transparent;
}

/* ── switch ──
   Checkbox-backed toggle. Rose when on; paper focus ring (dark surfaces). */

.switch {
  position: relative;
  display: inline-flex;
  flex-shrink: 0;
  cursor: pointer;
}

.switch input {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  opacity: 0;
  cursor: pointer;
}

.switch__track {
  width: 44px;
  height: 24px;
  border-radius: var(--radius-pill);
  background: var(--noir-600);
  position: relative;
  transition: background var(--duration-base) var(--ease-out);
}

.switch__track::after {
  content: '';
  position: absolute;
  top: 3px;
  left: 3px;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: var(--color-surface-raised);
  transition: transform var(--duration-base) var(--ease-out);
}

.switch input:checked + .switch__track {
  background: var(--rose-500);
}

.switch input:checked + .switch__track::after {
  transform: translateX(20px);
}

.switch input:focus-visible + .switch__track {
  outline: 2px solid var(--color-text-inverse);
  outline-offset: 2px;
}

/* context: on rose surfaces (dialog, banners) — a rose hover fill would
   vanish against the panel, so hover flips to paper instead */
.btn.on-rose.primary {
  --btn-bg-hover: var(--color-surface-raised);
  --btn-fg-hover: var(--noir-950);
  --btn-bg-pressed: var(--noir-100);
  --btn-fg-pressed: var(--noir-950);
}

/* ── type utilities (t-scale from the design system) ──
   h1–h4 are display steps (Eveleth, ≥24px); h5 switches to the body
   face, h6 is the label/eyebrow style. Use for structured content
   pages; components keep their own internal type. */

.t-h1,
.t-h2,
.t-h3,
.t-h4 {
  font-family: var(--font-display);
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
  color: var(--color-text-primary);
}

.t-h1 { font-size: var(--text-h1); line-height: 1.05; }
.t-h2 { font-size: var(--text-h2); line-height: 1.15; }
.t-h3 { font-size: var(--text-h3); line-height: 1.2; }
.t-h4 { font-size: var(--text-h4); line-height: var(--leading-heading); }

.t-h5 {
  font-family: var(--font-body);
  font-weight: 600;
  font-size: var(--text-h5);
  line-height: 1.4;
  color: var(--color-text-primary);
}

.t-h6 {
  font-family: var(--font-accent);
  font-weight: 400;
  font-size: 13px;
  line-height: 1.4;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-text-muted);
}

.t-body-lg { font-family: var(--font-body); font-size: var(--text-body-lg); line-height: 1.7; color: var(--color-text-soft); }
.t-body { font-family: var(--font-body); font-size: var(--text-body); line-height: 1.625; color: var(--color-text-primary); }
.t-body-sm { font-family: var(--font-body); font-size: var(--text-body-sm); line-height: 1.55; color: var(--color-text-soft); }
.t-micro { font-family: var(--font-body); font-size: 13px; line-height: 1.45; letter-spacing: 0.02em; color: var(--color-text-muted); }
.t-mono { font-family: var(--font-mono); font-size: 13px; line-height: 1.5; color: var(--color-text-soft); }

/* ── field ──
   Visible label + solid input + inline error. States: hover (inner
   border reinforces), focus (ink ring — visible on rose and paper),
   invalid (error border + message announced via aria-describedby). */

.field {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

.field__label {
  font-family: var(--font-accent);
  font-size: 12px;
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
}

.input {
  width: 100%;
  min-height: 44px;
  background: var(--field-bg);
  color: var(--field-fg);
  border: 1.5px solid var(--field-border);
  border-radius: var(--field-radius);
  padding: 10px 14px;
  font-family: var(--font-body);
  font-size: var(--text-body);
  transition: box-shadow var(--duration-fast) var(--ease-out);
  -webkit-appearance: none;
}

.input::placeholder {
  color: var(--field-placeholder);
}

.input:hover,
.input.is-hover {
  box-shadow: inset 0 0 0 1px var(--field-border);
}

.input:focus,
.input.is-focus {
  outline: 2px solid var(--noir-950);
  outline-offset: 2px;
}

/* error: heavy dark-red 3px ring (1.5px border + 1.5px outer shadow so
   the field never changes size). Never color alone — always paired with
   the icon + message chip via aria-describedby. */
.input[aria-invalid='true'] {
  border-color: var(--field-error);
  box-shadow: 0 0 0 1.5px var(--field-error);
}

.input[aria-invalid='true']:hover {
  box-shadow: 0 0 0 1.5px var(--field-error);
}

.input:disabled,
.input.is-disabled {
  background: var(--field-disabled-bg);
  color: var(--field-disabled-fg);
  border-color: var(--field-disabled-border);
  cursor: not-allowed;
  box-shadow: none;
}

.input:disabled::placeholder {
  color: var(--field-disabled-fg);
}

.checkbox[aria-invalid='true'] {
  outline: 2px solid var(--field-error);
  outline-offset: 2px;
}

.checkbox:disabled {
  accent-color: var(--noir-400);
  cursor: not-allowed;
}

/* display would override the hidden attribute — restore it explicitly */
.field__error[hidden] {
  display: none;
}

.field__error {
  align-self: flex-start;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: var(--field-bg);
  color: var(--field-error-text);
  font-family: var(--font-body);
  font-size: var(--text-small);
  font-weight: 500;
  padding: 3px 8px;
  border-radius: var(--field-radius);
}

.field__error::before {
  content: '';
  flex-shrink: 0;
  width: 14px;
  height: 14px;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Ccircle cx='8' cy='8' r='8' fill='%239C1F00'/%3E%3Crect x='7' y='3.5' width='2' height='6' rx='1' fill='%23fff'/%3E%3Crect x='7' y='11' width='2' height='2' rx='1' fill='%23fff'/%3E%3C/svg%3E") no-repeat center / contain;
}

/* checkbox — native control, brand-inked, with a visible focus ring */
.checkbox {
  width: 18px;
  height: 18px;
  flex-shrink: 0;
  accent-color: var(--noir-950);
  cursor: pointer;
}

.checkbox:focus-visible {
  outline: 2px solid var(--noir-950);
  outline-offset: 2px;
}

/* context: on ink surfaces / video — primary inverts to paper so it
   never melts into the background; hover keeps the rose flip */
.btn.on-dark.primary {
  --btn-bg: var(--color-surface-base-dim);
  --btn-fg: var(--noir-950);
  --btn-bg-hover: var(--rose-400);
  --btn-fg-hover: var(--noir-950);
  --btn-bg-pressed: var(--rose-300);
  --btn-fg-pressed: var(--noir-950);
}

.btn.on-dark.secondary {
  --btn-fg: var(--color-text-inverse);
  --btn-border: var(--color-text-inverse);
  --btn-bg-hover: var(--color-surface-base-dim);
  --btn-fg-hover: var(--noir-950);
  --btn-border-hover: var(--color-surface-base-dim);
  --btn-bg-pressed: var(--noir-100);
}

.btn.on-dark.link {
  --btn-fg-hover: var(--color-accent-on-dark);
  --btn-fg-pressed: var(--color-accent-on-dark);
}
