@charset "utf-8";
/* ==========================================================================
   /keyboard-polling-rate-calculator/ — tool.css
   Page-specific rules only. Everything structural (card, metrics, table,
   notes, buttons, forms) comes from design-system.css.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1 — The two linked fields
   Stacked on narrow screens, side by side with a conversion arrow between them
   from 560px.
   -------------------------------------------------------------------------- */

.calc__io {
  display: grid;
  gap: 0.85rem;
  align-items: start;
}

@media (min-width: 560px) {
  .calc__io {
    grid-template-columns: 1fr auto 1fr;
    gap: 0.85rem 1rem;
  }
}

/* The arrow is decorative (aria-hidden); the labels carry the meaning. */
.calc__link {
  justify-self: center;
  font-family: var(--mono);
  font-size: 1.25rem;
  line-height: 1;
  color: var(--text-2);
}

@media (min-width: 560px) {
  /* Sits level with the inputs, below the label row. */
  .calc__link { margin-block-start: 2.15rem; }
}

.calc__inputwrap {
  position: relative;
  inline-size: 100%;
  min-inline-size: 0;
}

/* Room for the unit suffix. The native spinners are removed because the suffix
   would sit on top of them; the preset buttons cover quick adjustment and the
   arrow keys still work in the field. */
.calc__inputwrap input[type="number"] {
  padding-inline-end: 3rem;
  -moz-appearance: textfield;
  appearance: textfield;
}

.calc__inputwrap input[type="number"]::-webkit-outer-spin-button,
.calc__inputwrap input[type="number"]::-webkit-inner-spin-button {
  -webkit-appearance: none;
  appearance: none;
  margin: 0;
}

.calc__suffix {
  position: absolute;
  inset-inline-end: 0.75rem;
  inset-block-start: 50%;
  transform: translateY(-50%);
  font-family: var(--mono);
  font-size: 0.8125rem;
  color: var(--text-2);
  pointer-events: none;
}

/* --------------------------------------------------------------------------
   2 — Inline validation / clamp messages
   Live regions that stay in the DOM and collapse when empty, so a screen
   reader announces the text rather than the region appearing.
   -------------------------------------------------------------------------- */

.calc__msg {
  display: flex;
  align-items: flex-start;
  gap: 0.4rem;
  font-size: 0.8125rem;
  line-height: 1.45;
  color: var(--bad);
}

.calc__msg:empty { display: none; }

.calc__msg::before {
  content: "!";
  flex: none;
  display: flex;
  align-items: center;
  justify-content: center;
  inline-size: 1.15em;
  block-size: 1.15em;
  margin-block-start: 0.12em;
  border: 1px solid currentColor;
  border-radius: 50%;
  font-family: var(--font);
  font-size: 0.6875rem;
  font-weight: 700;
  line-height: 1;
}

/* Clamp notices are informational, not errors. */
.calc__msg--note { color: var(--warn); }
.calc__msg--note::before { content: "i"; }

/* --------------------------------------------------------------------------
   3 — Formula strip + preset row
   -------------------------------------------------------------------------- */

.calc__formula {
  margin-block-start: 0.9rem;
  color: var(--text-2);
  overflow-wrap: anywhere;
}

.calc__presets { margin-block-start: 0.85rem; }

/* Pressed state carries a tick as well as the colour, per the a11y contract. */
.preset[aria-pressed="true"] {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 14%, var(--surface-2));
  color: var(--text);
}

.preset[aria-pressed="true"]::before {
  content: "\2713";
  font-size: 0.875em;
  line-height: 1;
  color: var(--accent);
}

/* --------------------------------------------------------------------------
   4 — Value + unit on one line
   .metric__value is display:block in the design system, so the unit needs a
   flex line of its own to sit beside it instead of dropping underneath.
   -------------------------------------------------------------------------- */

.metric__vu {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  min-inline-size: 0;
}

/* --------------------------------------------------------------------------
   5 — Two-rate comparison
   -------------------------------------------------------------------------- */

.calc__pair {
  display: grid;
  gap: 0.85rem;
}

@media (min-width: 560px) {
  .calc__pair { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* --------------------------------------------------------------------------
   6 — Selected row in the reference table
   The "Selected" pill is the non-colour cue; the tint and rule are extra.
   -------------------------------------------------------------------------- */

.tbl tbody tr.is-selected th,
.tbl tbody tr.is-selected td {
  background: color-mix(in srgb, var(--accent) 9%, transparent);
}

.tbl tbody tr.is-selected th { box-shadow: inset 3px 0 0 var(--accent); }

.calc-sel {
  margin-inline-start: 0.4rem;
  vertical-align: middle;
}
