/*
  Components: buttons, fields, cards and lists, tables, alerts, dialog, empty state.
  Uses tokens from tokens.css only. Every component is shown on /styleguide.
  Rules: docs/design.md.
*/

/* ================= Buttons ================= */
/* One prominent (primary) button per view. Same size for options in a set. */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-height: var(--control-h);
  min-width: var(--hit);
  padding: 0 var(--space-5);
  border: 0;
  border-radius: var(--radius-md);
  background: var(--accent-tint);
  color: var(--link);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  font-weight: var(--fw-semibold);
  text-align: center;
  text-decoration: none;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: filter var(--duration) var(--ease), opacity var(--duration) var(--ease);
}

.btn:hover {
  text-decoration: none;
  filter: brightness(0.96);
}

/* Press state (HIG: every custom button needs one) */
.btn:active {
  filter: brightness(0.88);
  opacity: 0.85;
}

.btn-primary {
  background: var(--accent);
  color: var(--on-accent);
}

/* Destructive: red, but never the prominent style (HIG: no primary role) */
.btn-destructive {
  background: var(--error-bg);
  color: var(--error);
}

.btn-plain {
  background: transparent;
  color: var(--link);
}

.btn-plain:hover,
.btn-plain:active {
  background: var(--fill-pressed);
  filter: none;
}

.btn-small {
  min-height: var(--hit);
  padding: 0 var(--space-4);
  font-size: var(--fs-callout);
  line-height: var(--lh-callout);
}

.btn-block {
  display: flex;
  width: 100%;
}

.btn:disabled,
.btn[aria-disabled="true"] {
  opacity: 0.4;
  cursor: not-allowed;
  filter: none;
}

/* Busy: add .is-loading and aria-busy="true". The label stays visible. */
.btn.is-loading {
  pointer-events: none;
}

.btn.is-loading::before {
  content: "";
  width: 1rem;
  height: 1rem;
  border: 2px solid currentColor;
  border-right-color: transparent;
  border-radius: var(--radius-full);
  animation: spin 0.8s linear infinite;
}

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

/* Row of buttons: stacked on phones (main action on top), in a row on wide screens
   (main action on the trailing side). */
.btn-row {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

@media (min-width: 30rem) {
  .btn-row {
    flex-direction: row-reverse;
    justify-content: flex-start;
  }

  .btn-row .btn {
    flex: 0 1 auto;
  }
}

/* ================= Fields ================= */
/* Always show a visible label. Placeholders disappear when typing. */

.field + .field,
.field + .btn,
.field + .btn-row {
  margin-top: var(--space-5);
}

.field-label {
  display: block;
  margin-bottom: var(--space-2);
  font-size: var(--fs-subhead);
  line-height: var(--lh-subhead);
  font-weight: var(--fw-semibold);
}

/* 16px or larger keeps iOS Safari from zooming when a field gets focus. */
.input,
.textarea,
.select {
  display: block;
  width: 100%;
  min-height: var(--control-h);
  padding: 0 var(--space-4);
  border: 1px solid var(--control-border);
  border-radius: var(--radius-md);
  background: var(--bg-secondary);
  color: var(--label);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  appearance: none;
  -webkit-appearance: none;
  transition: border-color var(--duration) var(--ease), box-shadow var(--duration) var(--ease);
}

.textarea {
  min-height: 7.5rem;
  padding: var(--space-3) var(--space-4);
  resize: vertical;
}

.select {
  padding-right: var(--space-10);
  background-image: linear-gradient(45deg, transparent 50%, var(--label-secondary) 50%),
    linear-gradient(135deg, var(--label-secondary) 50%, transparent 50%);
  background-position: calc(100% - 1.375rem) 50%, calc(100% - 1rem) 50%;
  background-size: 0.375rem 0.375rem, 0.375rem 0.375rem;
  background-repeat: no-repeat;
}

.input::placeholder,
.textarea::placeholder {
  color: var(--label-secondary);
}

.input:focus,
.textarea:focus,
.select:focus {
  outline: none;
  border-color: var(--link);
  box-shadow: 0 0 0 3px var(--accent-tint), 0 0 0 4px var(--link);
}

.input:disabled,
.textarea:disabled,
.select:disabled {
  opacity: 0.5;
  cursor: not-allowed;
  background: var(--bg-tertiary);
}

.field-hint,
.field-error {
  margin-top: var(--space-2);
  font-size: var(--fs-footnote);
  line-height: var(--lh-footnote);
}

.field-hint {
  color: var(--label-secondary);
}

/* Errors use an icon and text, never color alone. */
.field-error {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
  color: var(--error);
  font-weight: var(--fw-medium);
}

.field-error .icon {
  width: 1.125rem;
  height: 1.125rem;
  margin-top: 1px;
}

.field-invalid .input,
.field-invalid .textarea,
.field-invalid .select,
.input[aria-invalid="true"] {
  border-color: var(--error);
  border-width: 2px;
}

/* ================= Cards and grouped lists ================= */

.card {
  background: var(--bg-secondary);
  border-radius: var(--radius-md);
  padding: var(--space-5);
}

.card > * + * {
  margin-top: var(--space-5);
}

.group + .group {
  margin-top: var(--space-8);
}

/* Section header and footer text around a grouped list */
.group-title {
  margin: 0 var(--space-4) var(--space-2);
  color: var(--label-secondary);
  font-size: var(--fs-footnote);
  line-height: var(--lh-footnote);
  font-weight: var(--fw-medium);
  text-transform: uppercase;
  letter-spacing: 0.02em;
}

.group-note {
  margin: var(--space-2) var(--space-4) 0;
  color: var(--label-secondary);
  font-size: var(--fs-footnote);
  line-height: var(--lh-footnote);
}

.list {
  margin: 0;
  padding: 0;
  list-style: none;
  background: var(--bg-secondary);
  border-radius: var(--radius-md);
  overflow: hidden;
}

.list-row {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-height: var(--row-h);
  padding: var(--space-2) var(--space-4);
  color: var(--label);
  text-decoration: none;
}

/* Separator starts at the text, not at the edge (iOS grouped list) */
.list > li + li > .list-row::before,
.list > .list-row + .list-row::before {
  content: "";
  position: absolute;
  top: 0;
  left: var(--space-4);
  right: 0;
  border-top: 1px solid var(--separator);
}

a.list-row:hover {
  background: var(--fill-pressed);
  text-decoration: none;
}

a.list-row:active {
  background: var(--fill-pressed);
}

.list-row-main {
  flex: 1;
  min-width: 0;
}

.list-row-title {
  display: block;
}

.list-row-subtitle {
  display: block;
  color: var(--label-secondary);
  font-size: var(--fs-subhead);
  line-height: var(--lh-subhead);
}

.list-row-detail {
  color: var(--label-secondary);
  text-align: right;
}

.list-row .chevron {
  width: 1.25rem;
  height: 1.25rem;
  color: var(--label-tertiary);
}

/* ================= Tables ================= */
/* Use for data with several columns. Scrolls sideways inside its card on phones. */

.table-wrap {
  overflow-x: auto;
  background: var(--bg-secondary);
  border-radius: var(--radius-md);
  -webkit-overflow-scrolling: touch;
}

.table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--fs-callout);
  line-height: var(--lh-callout);
}

.table caption {
  padding: var(--space-4) var(--space-4) var(--space-2);
  text-align: left;
  font-size: var(--fs-headline);
  line-height: var(--lh-headline);
  font-weight: var(--fw-semibold);
}

.table th,
.table td {
  min-height: var(--hit);
  padding: var(--space-3) var(--space-4);
  text-align: left;
  vertical-align: middle;
  white-space: nowrap;
}

.table th {
  color: var(--label-secondary);
  font-size: var(--fs-footnote);
  line-height: var(--lh-footnote);
  font-weight: var(--fw-semibold);
  border-bottom: 1px solid var(--separator);
}

.table td {
  border-bottom: 1px solid var(--separator);
}

.table tbody tr:last-child td {
  border-bottom: 0;
}

.table tbody tr:hover {
  background: var(--fill-pressed);
}

/* Numbers: right-aligned, equal-width digits */
.table .num {
  text-align: right;
  font-variant-numeric: tabular-nums;
}

/* ================= Alerts and flash messages ================= */
/* Inline messages. They stay until the person dismisses them (no timers). */

.alert {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  padding: var(--space-4);
  border-radius: var(--radius-md);
  background: var(--info-bg);
  color: var(--label);
}

.alert-icon {
  margin-top: 1px;
  color: var(--info);
}

.alert-body {
  flex: 1;
  min-width: 0;
}

.alert-title {
  font-weight: var(--fw-semibold);
}

.alert-text {
  margin-top: var(--space-1);
  font-size: var(--fs-callout);
  line-height: var(--lh-callout);
}

.alert-success {
  background: var(--success-bg);
}

.alert-success .alert-icon {
  color: var(--success);
}

.alert-warning {
  background: var(--warning-bg);
}

.alert-warning .alert-icon {
  color: var(--warning);
}

.alert-error {
  background: var(--error-bg);
}

.alert-error .alert-icon {
  color: var(--error);
}

.alert-close {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--hit);
  height: var(--hit);
  margin: calc(var(--space-3) * -1) calc(var(--space-3) * -1) calc(var(--space-3) * -1) 0;
  border: 0;
  border-radius: var(--radius-full);
  background: transparent;
  color: var(--label-secondary);
  cursor: pointer;
}

.alert-close:hover {
  background: var(--fill-pressed);
}

/* ================= Copyable value ================= */
/* A value the person must copy once, for example a temporary password. One click selects all. */

.copy-value {
  display: block;
  padding: var(--space-3) var(--space-4);
  font-size: var(--fs-title-3);
  line-height: var(--lh-title-3);
  letter-spacing: 0.04em;
  overflow-wrap: anywhere;
  user-select: all;
  -webkit-user-select: all;
}

/* ================= Dialog (confirm) ================= */
/* For rare, serious decisions only: an action that cannot be undone. */

.dialog {
  width: min(calc(100vw - 2rem), 24rem);
  padding: var(--space-6);
  border: 0;
  border-radius: var(--radius-lg);
  background: var(--bg-elevated);
  color: var(--label);
  box-shadow: var(--shadow-dialog);
}

.dialog::backdrop {
  background: var(--scrim);
}

.dialog-title {
  font-size: var(--fs-headline);
  line-height: var(--lh-headline);
  font-weight: var(--fw-semibold);
}

.dialog-text {
  margin-top: var(--space-2);
  color: var(--label-secondary);
  font-size: var(--fs-callout);
  line-height: var(--lh-callout);
}

.dialog .btn-row {
  margin-top: var(--space-6);
}

/* ================= Empty state ================= */
/* Say what is missing and what to do next. */

.empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-10) var(--space-6);
  background: var(--bg-secondary);
  border-radius: var(--radius-md);
  text-align: center;
}

.empty-icon {
  width: 3rem;
  height: 3rem;
  margin-bottom: var(--space-2);
  color: var(--label-tertiary);
}

.empty-title {
  font-size: var(--fs-title-3);
  line-height: var(--lh-title-3);
  font-weight: var(--fw-semibold);
}

.empty-text {
  max-width: 28rem;
  color: var(--label-secondary);
}

.empty .btn {
  margin-top: var(--space-4);
}

/* ================= Segmented control (sub-tabs) ================= */
/* Closely related views of one page. Labels are nouns. Two to five segments. */

.page-tabs {
  margin-bottom: var(--space-6);
}

.segmented {
  display: inline-flex;
  gap: 2px;
  padding: 2px;
  background: var(--fill);
  border-radius: var(--radius-md);
}

.segment {
  display: flex;
  flex: 1 1 0;
  align-items: center;
  justify-content: center;
  min-width: 9rem;
  min-height: 2.5rem;
  padding: 0 var(--space-4);
  border-radius: calc(var(--radius-md) - 2px);
  color: var(--label);
  font-size: var(--fs-callout);
  line-height: var(--lh-callout);
  font-weight: var(--fw-medium);
  text-align: center;
  text-decoration: none;
  transition: background var(--duration) var(--ease);
}

.segment:hover {
  text-decoration: none;
  background: var(--fill-pressed);
}

/* Selected: lighter pill and heavier text, not color alone */
.segment[aria-current="page"] {
  background: var(--fill-selected);
  font-weight: var(--fw-semibold);
}

/* ================= Widget (a small report on one outside service) ================= */

.widget {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
  max-width: var(--content-w);
  padding: var(--space-6);
  background: var(--bg-secondary);
  border-radius: var(--radius-md);
}

.widget-header {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-2) var(--space-4);
}

/* Status: icon and words, never color alone */
.widget-status {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  color: var(--label-secondary);
  font-size: var(--fs-subhead);
  line-height: var(--lh-subhead);
}

.widget-status .icon {
  width: 1.125rem;
  height: 1.125rem;
}

.widget-note,
.widget-link {
  color: var(--label-secondary);
  font-size: var(--fs-footnote);
  line-height: var(--lh-footnote);
}

.widget-about {
  color: var(--label-secondary);
  font-size: var(--fs-callout);
  line-height: var(--lh-callout);
}

.widget-form {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  padding-top: var(--space-5);
  border-top: 1px solid var(--separator);
}

.widget-form .field + .field,
.widget-form .field + .btn {
  margin-top: 0;
}

.widget-actions form {
  display: contents;
}

/* Big numbers with a small label above */
.stats {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4) var(--space-10);
  margin: 0;
}

.stat dt {
  color: var(--label-secondary);
  font-size: var(--fs-footnote);
  line-height: var(--lh-footnote);
}

.stat dd {
  margin: 0;
  font-size: var(--fs-title-1);
  line-height: var(--lh-title-1);
  font-weight: var(--fw-bold);
  font-variant-numeric: tabular-nums;
}

/* ================= Meter (progress bar) ================= */
/* Built on <progress>, so it needs no inline style. Always write the percentage as text too. */

.meter {
  --meter: var(--accent);
  display: block;
  width: 100%;
  height: 0.75rem;
  border: 0;
  border-radius: var(--radius-full);
  background: var(--fill);
  overflow: hidden;
  appearance: none;
  -webkit-appearance: none;
}

.meter::-webkit-progress-bar {
  background: var(--fill);
}

.meter::-webkit-progress-value {
  background: var(--meter);
  border-radius: var(--radius-full);
}

.meter::-moz-progress-bar {
  background: var(--meter);
  border-radius: var(--radius-full);
}

.meter-warning {
  --meter: var(--warning);
}

.meter-error {
  --meter: var(--error);
}

/* Both ends of the range, as the HIG asks for gauges */
.meter-scale {
  display: flex;
  justify-content: space-between;
  margin-top: calc(var(--space-3) * -1);
  color: var(--label-secondary);
  font-size: var(--fs-caption-1);
  line-height: var(--lh-caption-1);
  font-variant-numeric: tabular-nums;
}

.meter-caption {
  margin-top: calc(var(--space-3) * -1);
  color: var(--label-secondary);
  font-size: var(--fs-footnote);
  line-height: var(--lh-footnote);
}
