/* Hoppy Clock USB configuration UI. */

:root {
  color-scheme: light dark;

  --bg: #f6f7f9;
  --surface: #ffffff;
  --border: #dfe3e8;
  --text: #1a1d21;
  --text-dim: #5f6874;
  --accent: #2f6fdd;
  --accent-text: #ffffff;
  --ok: #1a7f4b;
  --warn: #9a6400;
  --err: #b3261e;
  --warn-bg: #fff8e6;

  --radius: 10px;
  --gap: 1rem;
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #14171a;
    --surface: #1c2024;
    --border: #2e343b;
    --text: #e7eaee;
    --text-dim: #98a2ae;
    --accent: #5b95f0;
    --accent-text: #0d1013;
    --ok: #4bc98a;
    --warn: #e0ab4a;
    --err: #f2837a;
    --warn-bg: #2a2519;
  }
}

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  padding: 0 var(--gap) 3rem;
  background: var(--bg);
  color: var(--text);
  font: 16px/1.55 system-ui, -apple-system, "Segoe UI", sans-serif;
}

main,
.hero,
.foot,
.topbar__inner {
  max-width: 54rem;
  margin: 0 auto;
}

/* Site bar. Bleeds over the body padding so the rule under it runs the full
   width, while its contents line up with the cards below. */

.topbar {
  position: sticky;
  top: 0;
  z-index: 10;
  margin: 0 calc(var(--gap) * -1);
  padding: 0.85rem var(--gap);
  background: var(--bg);
  border-bottom: 1px solid var(--border);
}

.topbar__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--gap);
  flex-wrap: wrap;
}

.brand {
  font-size: 0.95rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text);
  text-decoration: none;
}

.brand:hover,
.brand:focus-visible {
  color: var(--accent);
}

.topbar__actions {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}

/* What the thing is, before any of the controls for it. */

.hero {
  padding: 1.6rem 0 1.4rem;
}

.hero h1 {
  margin: 0;
  font-size: 1.9rem;
  letter-spacing: -0.02em;
}

.hero__blurb {
  max-width: 42rem;
  margin: 0.5rem 0 0;
  color: var(--text-dim);
}

.hero__links {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem 1.25rem;
  margin: 0.85rem 0 0;
  font-size: 0.9rem;
}

.hero__link {
  color: var(--accent);
  font-weight: 600;
  text-decoration: none;
}

.hero__link:hover,
.hero__link:focus-visible {
  text-decoration: underline;
}

/* A link whose destination does not exist yet. */
.is-pending {
  color: var(--text-dim);
  font-weight: 400;
  cursor: default;
}

.is-pending:hover {
  text-decoration: none;
}

.pill {
  padding: 0.2rem 0.6rem;
  border: 1px solid var(--border);
  border-radius: 999px;
  font-size: 0.8rem;
  font-weight: 600;
  white-space: nowrap;
}

.pill--idle {
  color: var(--text-dim);
}

.pill--busy {
  color: var(--warn);
  border-color: currentcolor;
}

.pill--live {
  color: var(--ok);
  border-color: currentcolor;
}

.pill--err {
  color: var(--err);
  border-color: currentcolor;
}

/* Buttons.
   Tone says what the action does, and reads at a glance:
     filled accent  the panel's main commit, at most one per panel
     outlined       another write to the clock
     quiet          reads and form resets, nothing leaves the page
     red            destroys something stored
   Size is a separate axis, so a row button can carry any tone. */

.btn {
  padding: 0.45rem 0.95rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--text);
  font: inherit;
  font-size: 0.92rem;
  cursor: pointer;
}

.btn:hover:not(:disabled) {
  border-color: var(--accent);
}

.btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.btn--primary {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-text);
  font-weight: 600;
}

/* Reserved for actions that destroy stored data. */
.btn--danger {
  border-color: var(--err);
  color: var(--err);
  font-weight: 600;
}

.btn--danger:hover:not(:disabled) {
  background: var(--err);
  color: var(--surface);
  border-color: var(--err);
}

/* Quiet: no frame until you reach for it. */
.btn--ghost {
  border-color: transparent;
  background: none;
  font-weight: 400;
  color: var(--text-dim);
}

.btn--ghost:hover:not(:disabled) {
  border-color: var(--border);
  color: var(--text);
}

/* For rows and card headings, where a full-size button would dominate. */
.btn--sm {
  padding: 0.15rem 0.55rem;
  font-size: 0.78rem;
}

/* Tabs. */

.tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 0.15rem;
  margin: 0 0 var(--gap);
  border-bottom: 1px solid var(--border);
}

.tab {
  padding: 0.55rem 0.95rem;
  border: none;
  border-bottom: 2px solid transparent;
  background: none;
  color: var(--text-dim);
  font: inherit;
  font-size: 0.95rem;
  font-weight: 600;
  cursor: pointer;
}

.tab:hover {
  color: var(--text);
}

.tab[aria-selected="true"] {
  color: var(--accent);
  border-bottom-color: var(--accent);
}

.tab:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -4px;
}

/* Cards. */

.card {
  margin: 0 0 var(--gap);
  padding: 1.1rem 1.25rem 1.25rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
}

/* Two or more buttons in a card heading stay grouped on the right. */
.card__actions {
  display: flex;
  gap: 0.4rem;
}

.card h2 {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--gap);
  margin: 0 0 0.75rem;
  font-size: 0.8rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-dim);
}

.card--warn {
  border-color: var(--warn);
  background: var(--warn-bg);
}

.card--warn h2 {
  color: var(--warn);
  font-size: 1rem;
  letter-spacing: normal;
  text-transform: none;
}

.steps {
  margin: 0;
  padding-left: 1.2rem;
}

.steps li + li {
  margin-top: 0.35rem;
}

.note {
  margin: 0.75rem 0 0;
  color: var(--text-dim);
  font-size: 0.86rem;
}

code {
  padding: 0.05em 0.35em;
  border-radius: 4px;
  background: color-mix(in srgb, var(--text) 8%, transparent);
  font-family: ui-monospace, "Cascadia Code", Consolas, monospace;
  font-size: 0.88em;
}

/* Time readout. */

.readout {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
  gap: var(--gap);
}

.readout__item {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
}

.readout__label {
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--text-dim);
}

.readout__value {
  font-family: ui-monospace, "Cascadia Code", Consolas, monospace;
  font-size: 1.7rem;
  font-variant-numeric: tabular-nums;
  line-height: 1.15;
}

.readout__unit {
  font-family: system-ui, -apple-system, "Segoe UI", sans-serif;
  font-size: 0.95rem;
  font-weight: 500;
}

.readout__sub {
  font-size: 0.82rem;
  color: var(--text-dim);
  font-variant-numeric: tabular-nums;
}

/* Drift severity, set from app.js. */

.is-ok {
  color: var(--ok);
}

.is-warn {
  color: var(--warn);
}

.is-err {
  color: var(--err);
}

.actions {
  display: flex;
  align-items: center;
  gap: 0.85rem;
  flex-wrap: wrap;
  margin-top: 1.25rem;
  padding-top: 1rem;
  border-top: 1px solid var(--border);
}

.actions .note {
  margin: 0;
}

/* Row lists: alarms, light looks and sound slots share one shape. */

.alarms,
.lights,
.sounds {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  margin: 0.75rem 0 0;
  padding: 0;
  list-style: none;
}

.alarm,
.light,
.sound {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 0.1rem 0.9rem;
  padding: 0.6rem 0.75rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
}

/* The action sits on the right, spanning both rows of the item. */
.alarm .btn,
.light .btn,
.sound .btn {
  grid-column: 3;
  grid-row: 1 / 3;
}

/* Stored but inert: a disabled alarm, an empty sound slot. */
.alarm--off,
.sound--empty {
  opacity: 0.55;
}

/* Alarms. */

.alarm__time {
  grid-row: 1 / 3;
  font-family: ui-monospace, "Cascadia Code", Consolas, monospace;
  font-size: 1.3rem;
  font-variant-numeric: tabular-nums;
}

.alarm__when {
  grid-column: 2;
  font-size: 0.92rem;
  font-weight: 600;
}

.alarm__meta {
  grid-column: 2;
  font-size: 0.82rem;
  color: var(--text-dim);
}

/* Lights. */

/* A dot of the colour the look settles on, brightness included. */
.light__swatch {
  grid-row: 1 / 3;
  width: 1.9rem;
  height: 1.9rem;
  border: 1px solid var(--border);
  border-radius: 50%;
}

.light__name {
  grid-column: 2;
  font-size: 0.92rem;
  font-weight: 600;
  text-transform: capitalize;
}

.light__meta {
  grid-column: 2;
  font-size: 0.82rem;
  color: var(--text-dim);
}

/* Sounds. */

.sound__id {
  grid-row: 1 / 3;
  font-family: ui-monospace, "Cascadia Code", Consolas, monospace;
  font-size: 1.3rem;
  font-variant-numeric: tabular-nums;
}

.sound__name {
  grid-column: 2;
  font-size: 0.92rem;
  font-weight: 600;
}

.sound__meta {
  grid-column: 2;
  font-size: 0.82rem;
  color: var(--text-dim);
}

/* Blocks inside a card: the lamp pickers, the LED chain. */

.subsection {
  margin-top: 1.1rem;
  padding-top: 0.9rem;
  border-top: 1px solid var(--border);
}

.subsection__title {
  margin: 0;
  font-size: 0.95rem;
}

.subsection .note {
  margin-top: 0.3rem;
}

.subsection .field-row {
  align-items: flex-end;
}

/* Add-alarm form. */

.adder {
  margin-top: 1.1rem;
  padding-top: 0.9rem;
  border-top: 1px solid var(--border);
}

.adder summary {
  cursor: pointer;
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--accent);
}

.adder__more {
  margin-top: 0.9rem;
}

.adder__more summary {
  font-weight: 400;
  color: var(--text-dim);
}

.field-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--gap);
  margin-top: 0.9rem;
}

.field {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}

.field__label {
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--text-dim);
}

.days {
  display: flex;
  flex-wrap: wrap;
  gap: 0.45rem 0.9rem;
  margin: 0.9rem 0 0;
  padding: 0.7rem 0.85rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
}

.days legend {
  padding: 0 0.3rem;
}

.days label,
.inline {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  font-size: 0.9rem;
}

input[type="time"],
input[type="number"],
select {
  padding: 0.4rem 0.5rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--text);
  font: inherit;
  font-size: 0.92rem;
}

input[type="number"] {
  width: 7.5rem;
}

progress {
  width: 100%;
  height: 0.5rem;
  margin-top: 0.75rem;
  accent-color: var(--accent);
}

input[type="file"] {
  max-width: 100%;
  font-size: 0.88rem;
}

input[type="color"] {
  width: 4rem;
  height: 2.3rem;
  padding: 0.15rem;
}

/* The day picker and the day-of-month field swap on the repeat mode, and both
   set display, which would otherwise beat the browser's own [hidden] rule. */
[hidden] {
  display: none !important;
}

/* Log. */

.log {
  max-height: 15rem;
  margin: 0;
  overflow-y: auto;
  font-family: ui-monospace, "Cascadia Code", Consolas, monospace;
  font-size: 0.82rem;
  line-height: 1.6;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.log:empty::before {
  content: "Nothing yet.";
  color: var(--text-dim);
}

.log__line--err {
  color: var(--err);
}

.log__line--ok {
  color: var(--ok);
}

.log__time {
  color: var(--text-dim);
}

/* Idle (disconnected) state: dim the parts that need a live device, and show
   the connection instructions only while they are still relevant. */

body:not(.is-connected) #time-card,
body:not(.is-connected) #alarm-card,
body:not(.is-connected) #light-card,
body:not(.is-connected) #sound-card,
body:not(.is-connected) #reset-card {
  opacity: 0.55;
}

body.is-connected #connect-card {
  display: none;
}

.foot {
  padding-top: 1.5rem;
  font-size: 0.84rem;
  text-align: center;
}

.foot__links {
  display: flex;
  justify-content: center;
  gap: 0.6rem;
  margin: 0;
  color: var(--text-dim);
}

.foot a {
  color: var(--text-dim);
}

.foot a:hover {
  color: var(--accent);
}

.foot__note {
  max-width: 34rem;
  margin: 0.4rem auto 0;
  color: var(--text-dim);
  opacity: 0.8;
}
