/* ==========================================================================
   corporate-memphis-theme / components
   --------------------------------------------------------------------------
   Five components: button, card, input, badge, nav.

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

   The class names follow the shadcn shape: one base class carrying the
   structure, one variant class carrying the intent (cm-btn + cm-btn-primary).
   If you are on shadcn already, these map onto its variant prop directly.

   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 behavior
   Everything in this theme moves the same way: up by --cm-lift, on a curve
   that decelerates, with the shadow growing one step to account for the new
   distance. Under prefers-reduced-motion the lift token is zeroed and the
   duration collapses, so the shadow step still carries the state and nothing
   travels.
   -------------------------------------------------------------------------- */
.cm-liftable {
  transition:
    transform var(--cm-duration) var(--cm-ease),
    box-shadow var(--cm-duration) var(--cm-ease);
}

.cm-liftable:hover {
  transform: translateY(calc(var(--cm-lift) * -1));
  box-shadow: var(--cm-shadow-lg);
}

.cm-liftable:focus-visible,
.cm-focusable:focus-visible {
  outline: var(--cm-ring-width) solid var(--cm-ring);
  outline-offset: var(--cm-ring-offset);
}

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

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

  /* Fully round, which is the register's most reliable tell and the cheapest
     one to get wrong. A 14px radius on a 44px button looks like a different
     theme; the pill is what makes the control agree with the illustration. */
  border: var(--cm-border-width) solid transparent;
  border-radius: var(--cm-radius-pill);
  box-shadow: var(--cm-shadow-sm);
  cursor: pointer;

  transition:
    transform var(--cm-duration) var(--cm-ease),
    box-shadow var(--cm-duration) var(--cm-ease),
    background-color var(--cm-duration) var(--cm-ease);
}

.cm-btn:hover:not(:disabled) {
  transform: translateY(calc(var(--cm-lift) * -1));
  box-shadow: var(--cm-shadow);
}

/* The press puts the button back down. Hover raises, click lands, which keeps
   the two gestures telling different stories on a theme with no hard edges to
   read state from. */
.cm-btn:active:not(:disabled) {
  transform: translateY(0);
  box-shadow: var(--cm-shadow-sm);
}

.cm-btn:focus-visible {
  outline: var(--cm-ring-width) solid var(--cm-ring);
  outline-offset: var(--cm-ring-offset);
}

.cm-btn:disabled,
.cm-btn[aria-disabled="true"] {
  opacity: 0.5;
  cursor: not-allowed;
  transform: none;
  box-shadow: none;
}

.cm-btn-primary {
  background: var(--cm-primary);
  color: var(--cm-primary-ink);
}

.cm-btn-secondary {
  background: var(--cm-secondary);
  color: var(--cm-secondary-ink);
}

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

/* The quiet button is the one control in the theme that shows an edge, because
   it has no fill to be recognized by. It takes --cm-border-strong rather than
   the hairline: the outline of a button is a boundary a person has to find,
   and the hairline is decorative. */
.cm-btn-quiet {
  background: var(--cm-surface);
  color: var(--cm-ink);
  border-color: var(--cm-border-strong);
}

.cm-btn-quiet:hover:not(:disabled) {
  background: var(--cm-surface-soft);
}

.cm-btn-sm {
  min-height: 44px; /* the visual box shrinks, the touch target does not */
  padding: var(--cm-space-2) var(--cm-space-4);
  font-size: var(--cm-text-sm);
}

.cm-btn-lg {
  padding: var(--cm-space-4) var(--cm-space-8);
  font-size: var(--cm-text-lead);
  box-shadow: var(--cm-shadow);
}

.cm-btn-lg:hover:not(:disabled) {
  box-shadow: var(--cm-shadow-lg);
}

/* ==========================================================================
   CARD
   Variants: (base), cm-card-soft, cm-card-outlined
   Parts:    cm-card-header, cm-card-title, cm-card-body, cm-card-footer,
             cm-card-spot (the slot a spot illustration sits in)
   ========================================================================== */
.cm-card {
  display: flex;
  flex-direction: column;
  background: var(--cm-surface);
  color: var(--cm-ink);
  border: var(--cm-border-width) solid var(--cm-border);
  border-radius: var(--cm-radius-lg);
  box-shadow: var(--cm-shadow-sm);
  padding: var(--cm-space-6);
}

.cm-card-soft {
  background: var(--cm-surface-soft);
  border-color: transparent;
}

/* The outlined card carries no shadow, so its edge has to be real rather than
   a hairline that assumes an elevation doing the actual work. */
.cm-card-outlined {
  border-color: var(--cm-border-strong);
  box-shadow: none;
}

.cm-card-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--cm-space-4);
  margin-bottom: var(--cm-space-3);
}

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

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

.cm-card-footer {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--cm-space-3);
  margin-top: auto;
  padding-top: var(--cm-space-6);
}

/* The slot a spot illustration sits in. It is a fixed square rather than an
   auto height, so a row of three cards keeps its baselines even when one scene
   is drawn taller than another inside its own viewBox. */
.cm-card-spot {
  display: flex;
  align-items: center;
  justify-content: center;
  width: var(--cm-illo-spot);
  height: var(--cm-illo-spot);
  margin-bottom: var(--cm-space-4);
  border-radius: var(--cm-radius);
}

/* A card that is itself a link. */
.cm-card-link {
  text-decoration: none;
  transition:
    transform var(--cm-duration) var(--cm-ease),
    box-shadow var(--cm-duration) var(--cm-ease);
}

.cm-card-link:hover {
  transform: translateY(calc(var(--cm-lift) * -1));
  box-shadow: var(--cm-shadow);
}

.cm-card-link:active {
  transform: translateY(0);
  box-shadow: var(--cm-shadow-sm);
}

.cm-card-link:focus-visible {
  outline: var(--cm-ring-width) solid var(--cm-ring);
  outline-offset: var(--cm-ring-offset);
}

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

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

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

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

  /* --cm-border-strong, not the hairline. This is the boundary that tells a
     person where they may type, and a 1.34:1 edge does not tell anyone that. */
  border: var(--cm-border-width) solid var(--cm-border-strong);
  border-radius: var(--cm-radius);

  transition:
    border-color var(--cm-duration) var(--cm-ease),
    box-shadow var(--cm-duration) var(--cm-ease);
}

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

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

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

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

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

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

/* Textarea and select inherit the input treatment. */
.cm-input:where(textarea) {
  min-height: 120px;
  resize: vertical;
}

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

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

  /* Sentence case, not uppercase. An uppercase label addresses the reader as
     an operator, and Companion is the position that declines to. */
  color: var(--cm-ink);
  border-radius: var(--cm-radius-pill);
  white-space: nowrap;
}

.cm-badge-neutral {
  background: var(--cm-fill-neutral);
}

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

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

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

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

/* ==========================================================================
   CARD ROW
   The one grid in this theme whose column count is a decision rather than a
   consequence, which is why --cm-columns exists and why the Tailwind adapters
   hand over a track list rather than the count. A count is not a grid: mapped
   through --grid-template-columns-* directly it compiles to
   `grid-template-columns: 3`, which is a valid-looking rule that sets nothing.
   ========================================================================== */
.cm-cards {
  display: grid;
  gap: var(--cm-space-6);
  grid-template-columns: 1fr;
}

@media (min-width: 900px) {
  .cm-cards {
    grid-template-columns: repeat(var(--cm-columns), minmax(0, 1fr));
  }
}

/* ==========================================================================
   NAV
   A header bar with a brand block, inline links on desktop, and a disclosure
   panel on mobile. The disclosure is a <details> element, so the pattern
   needs no JavaScript and keeps working with the page's scripts disabled.
   ========================================================================== */
.cm-nav {
  background: var(--cm-surface);
  border-bottom: var(--cm-border-width) solid var(--cm-border);
}

.cm-nav-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--cm-space-4);
  max-width: var(--cm-container);
  margin: 0 auto;
  padding: var(--cm-space-3) var(--cm-space-4);
}

.cm-nav-brand {
  display: inline-flex;
  align-items: center;
  gap: var(--cm-space-3);
  font-family: var(--cm-font-sans);
  font-size: var(--cm-text-h3);
  font-weight: var(--cm-weight-display);
  letter-spacing: var(--cm-tracking-tight);
  color: var(--cm-ink);
  text-decoration: none;
}

/* The brand mark is a circle rather than a rounded square, because a circle is
   the shape the illustration is built from and the mark is the smallest place
   the two can agree. */
.cm-nav-mark {
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  background: var(--cm-primary);
  color: var(--cm-primary-ink);
  border-radius: var(--cm-radius-pill);
  font-size: var(--cm-text-body);
  font-weight: var(--cm-weight-display);
}

.cm-nav-links {
  display: none;
  align-items: center;
  gap: var(--cm-space-1);
  list-style: none;
  margin: 0;
  padding: 0;
}

.cm-nav-link {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: var(--cm-space-2) var(--cm-space-3);

  font-family: var(--cm-font-sans);
  font-size: var(--cm-text-sm);
  font-weight: var(--cm-weight-bold);
  color: var(--cm-ink);
  text-decoration: none;

  border-radius: var(--cm-radius-pill);
}

.cm-nav-link:hover {
  background: var(--cm-surface-soft);
}

/* The current page is marked by a fill rather than by an underline. An
   underline under a rounded pill reads as two competing shapes. */
.cm-nav-link[aria-current="page"] {
  background: var(--cm-fill-neutral);
}

.cm-nav-link:focus-visible {
  outline: var(--cm-ring-width) solid var(--cm-ring);
  outline-offset: var(--cm-ring-offset);
}

.cm-nav-cta {
  display: none;
}

/* Mobile disclosure */
.cm-nav-disclosure {
  position: relative;
}

.cm-nav-disclosure > summary {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--cm-space-2);
  min-width: 44px;
  min-height: 44px;
  padding: var(--cm-space-2) var(--cm-space-4);

  font-family: var(--cm-font-sans);
  font-size: var(--cm-text-sm);
  font-weight: var(--cm-weight-bold);
  color: var(--cm-ink);
  background: var(--cm-surface);

  border: var(--cm-border-width) solid var(--cm-border-strong);
  border-radius: var(--cm-radius-pill);
  cursor: pointer;
  list-style: none;
}

.cm-nav-disclosure > summary::-webkit-details-marker {
  display: none;
}

.cm-nav-disclosure > summary:focus-visible {
  outline: var(--cm-ring-width) solid var(--cm-ring);
  outline-offset: var(--cm-ring-offset);
}

.cm-nav-panel {
  position: absolute;
  right: 0;
  z-index: 20;
  min-width: 220px;
  margin-top: var(--cm-space-2);
  padding: var(--cm-space-2);

  list-style: none;
  background: var(--cm-surface);
  border: var(--cm-border-width) solid var(--cm-border);
  border-radius: var(--cm-radius-lg);
  box-shadow: var(--cm-shadow-lg);
}

.cm-nav-panel .cm-nav-link {
  display: flex;
  width: 100%;
}

/* At 768px the links come inline and the disclosure retires. */
@media (min-width: 768px) {
  .cm-nav-inner {
    padding: var(--cm-space-3) var(--cm-space-6);
  }

  .cm-nav-links,
  .cm-nav-cta {
    display: flex;
  }

  .cm-nav-disclosure {
    display: none;
  }
}
