/* ==========================================================================
   desktop-os-theme / components
   --------------------------------------------------------------------------
   Five components for the content that lives INSIDE a window: button, panel,
   badge, field, list. The window itself, the icons, the taskbar and the
   launcher are not here; they are the shell, and they live in
   shell/shell.css. That split is the point of this theme: these components
   would work on an ordinary page, and the shell would work around different
   components.

   There is not one color literal in this file, which is what makes
   retheming a matter of editing one file rather than auditing five. Every
   color, every duration and every piece of spacing is a var() reference to
   tokens.css.

   Six declarations carry a bare length, and the broader claim this header
   used to make was false. They are: the 44px control minimums on the button
   and the field (WCAG 2.5.8), the 36px small-button minimum, the 120px
   textarea floor, the 1px press travel, and the 2px keyboard-chip edge. The
   target minimums stay literal on purpose, because a token invites a
   re-skin to lower an accessibility floor.

   The class names follow the shadcn shape: one base class carrying the
   structure, one variant class carrying the intent (os-btn + os-btn-primary).

   Requires tokens.css to be loaded first. Load it explicitly rather than
   letting this file pull it in, so the dependency is visible at the call
   site:

     <link rel="stylesheet" href="tokens/tokens.css" />
     <link rel="stylesheet" href="components/components.css" />
   ========================================================================== */

/* --------------------------------------------------------------------------
   Shared focus. The ring is the accent, offset outside the element, on
   everything interactive.
   -------------------------------------------------------------------------- */
.os-btn:focus-visible,
.os-input:focus-visible,
.os-focusable:focus-visible {
  outline: var(--os-ring-width) solid var(--os-ring);
  outline-offset: var(--os-ring-offset);
}

/* ==========================================================================
   BUTTON
   Variants: os-btn-primary, os-btn-default, os-btn-ghost, os-btn-destructive
   Sizes:    os-btn-sm, (base)
   ========================================================================== */
.os-btn {
  /* 44px minimum on both axes. Anything smaller fails on a real thumb. */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--os-space-2);
  min-height: 44px;
  padding: var(--os-space-3) var(--os-space-6);

  font-family: var(--os-font-sans);
  font-size: var(--os-text-body);
  font-weight: var(--os-weight-medium);
  line-height: var(--os-leading-snug);
  text-decoration: none;
  white-space: nowrap;

  border: var(--os-border-width) solid var(--os-border-strong);
  border-radius: var(--os-radius);
  box-shadow: var(--os-shadow-sm);
  cursor: pointer;

  transition:
    transform var(--os-duration) var(--os-ease),
    box-shadow var(--os-duration) var(--os-ease);
}

/* The press is one pixel of travel and the shadow going flat: a click that
   feels mechanical without performing. */
.os-btn:active:not(:disabled) {
  transform: translateY(1px);
  box-shadow: none;
}

.os-btn:disabled,
.os-btn[aria-disabled="true"] {
  opacity: 0.5;
  cursor: not-allowed;
}

.os-btn-primary {
  background: var(--os-accent);
  color: var(--os-accent-ink);
  border-color: var(--os-accent);
}

.os-btn-default {
  background: var(--os-surface);
  color: var(--os-ink);
}

.os-btn-default:hover {
  background: var(--os-chrome);
}

.os-btn-destructive {
  background: var(--os-destructive);
  color: var(--os-destructive-ink);
  border-color: var(--os-destructive);
}

/* The ghost sits flat until hovered, which is how the reader learns it was
   a button all along. */
.os-btn-ghost {
  background: transparent;
  color: var(--os-ink);
  border-color: transparent;
  box-shadow: none;
}

.os-btn-ghost:hover {
  background: var(--os-surface-muted);
}

.os-btn-sm {
  min-height: 36px;
  padding: var(--os-space-1) var(--os-space-3);
  font-size: var(--os-text-sm);
}

/* ==========================================================================
   PANEL
   A surface inside a window. Variants: (base), os-panel-muted.
   Parts: os-panel-title, os-panel-body.
   ========================================================================== */
.os-panel {
  display: flex;
  flex-direction: column;
  gap: var(--os-space-2);
  padding: var(--os-space-4);

  background: var(--os-surface);
  color: var(--os-ink);
  border: var(--os-border-width) solid var(--os-border);
  border-radius: var(--os-radius);
  box-shadow: var(--os-shadow-sm);
}

.os-panel-muted {
  background: var(--os-surface-muted);
  box-shadow: none;
}

.os-panel-title {
  margin: 0;
  font-size: var(--os-text-h3);
  font-weight: var(--os-weight-bold);
  line-height: var(--os-leading-snug);
  letter-spacing: var(--os-tracking-tight);
}

.os-panel-body {
  margin: 0;
  color: var(--os-ink-muted);
  font-size: var(--os-text-body);
  line-height: var(--os-leading-body);
}

/* ==========================================================================
   BADGE
   Variants: os-badge-neutral, os-badge-success, os-badge-info,
             os-badge-warning, os-badge-danger
   ========================================================================== */
.os-badge {
  display: inline-flex;
  align-items: center;
  gap: var(--os-space-1);
  padding: var(--os-space-1) var(--os-space-2);

  font-family: var(--os-font-sans);
  font-size: var(--os-text-xs);
  font-weight: var(--os-weight-bold);
  line-height: var(--os-leading-snug);
  letter-spacing: var(--os-tracking-wide);
  text-transform: uppercase;

  /* Ink on every fill. Meaning lives in the hue; legibility never depends
     on it. */
  color: var(--os-ink);
  border: var(--os-border-width) solid var(--os-border);
  border-radius: var(--os-radius-tight);
  white-space: nowrap;
}

.os-badge-neutral {
  background: var(--os-surface-muted);
}

.os-badge-success {
  background: var(--os-fill-success);
}

.os-badge-info {
  background: var(--os-fill-info);
}

.os-badge-warning {
  background: var(--os-fill-warning);
}

.os-badge-danger {
  background: var(--os-fill-danger);
}

/* ==========================================================================
   FIELD
   Parts:  os-field, os-label, os-input, os-hint, os-error
   States: default, :focus, aria-invalid="true", :disabled
   ========================================================================== */
.os-field {
  display: flex;
  flex-direction: column;
  gap: var(--os-space-2);
}

.os-label {
  font-family: var(--os-font-sans);
  font-size: var(--os-text-sm);
  font-weight: var(--os-weight-bold);
  color: var(--os-ink);
}

.os-input {
  /* 16px minimum, which is what stops iOS Safari zooming on focus. */
  width: 100%;
  min-height: 44px;
  padding: var(--os-space-3) var(--os-space-4);

  font-family: var(--os-font-sans);
  font-size: var(--os-text-body);
  color: var(--os-ink);
  background: var(--os-surface);

  border: var(--os-border-width) solid var(--os-border-strong);
  border-radius: var(--os-radius);
}

.os-input::placeholder {
  color: var(--os-ink-muted);
}

.os-input:focus {
  outline: var(--os-ring-width) solid var(--os-ring);
  outline-offset: var(--os-ring-offset);
}

.os-input[aria-invalid="true"] {
  border-color: var(--os-destructive);
}

.os-input:disabled {
  background: var(--os-surface-muted);
  color: var(--os-ink-muted);
  cursor: not-allowed;
}

.os-hint {
  font-size: var(--os-text-sm);
  color: var(--os-ink-muted);
}

.os-error {
  font-size: var(--os-text-sm);
  font-weight: var(--os-weight-bold);
  color: var(--os-destructive);
}

/* Textarea inherits the input treatment. */
.os-input:where(textarea) {
  min-height: 120px;
  resize: vertical;
}

/* ==========================================================================
   LIST
   Settings-style rows: a name, an optional description, a value or control
   at the end. The shape a workspace product's windows are full of.
   Parts: os-list, os-list-row, os-list-name, os-list-desc, os-list-end
   ========================================================================== */
.os-list {
  margin: 0;
  padding: 0;
  list-style: none;
  border: var(--os-border-width) solid var(--os-border);
  border-radius: var(--os-radius);
  background: var(--os-surface);
  overflow: hidden;
}

.os-list-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--os-space-4);
  padding: var(--os-space-3) var(--os-space-4);
}

.os-list-row + .os-list-row {
  border-top: var(--os-border-width) solid var(--os-border);
}

.os-list-name {
  font-weight: var(--os-weight-medium);
  color: var(--os-ink);
}

.os-list-desc {
  display: block;
  font-size: var(--os-text-sm);
  color: var(--os-ink-muted);
}

.os-list-end {
  flex: none;
  font-family: var(--os-font-mono);
  font-size: var(--os-text-sm);
  color: var(--os-ink-muted);
}

/* A keyboard hint chip, for the shell's keyboard story. Real text in a kbd
   element, not an image of a key. */
.os-kbd {
  display: inline-block;
  padding: 0 var(--os-space-2);
  font-family: var(--os-font-mono);
  font-size: var(--os-text-xs);
  line-height: 1.8;
  color: var(--os-ink);
  background: var(--os-chrome);
  border: var(--os-border-width) solid var(--os-border-strong);
  border-bottom-width: 2px;
  border-radius: var(--os-radius-tight);
}
