:root {
  color: #18212b;
  background: #edf2f0;
  font-family: Georgia, 'Times New Roman', serif;
  line-height: 1.5;
}

* {
  box-sizing: border-box;
}

html,
body {
  height: 100%;
}

body {
  margin: 0;
  overflow: hidden;
}

main {
  display: flex;
  flex-direction: column;
  height: 100%;
  width: 100%;
  margin: 0;
  padding: 2rem 2rem 0;
}

header {
  flex: none;
  margin-bottom: 1.5rem;
}

/* Two-column shell: left = configuration (40%), right = API operations (60%,
   roomier for the button rows and queue tables). Each column scrolls
   independently so the page always fills the viewport. */
.layout {
  display: grid;
  flex: 1;
  gap: 1.5rem;
  grid-template-columns: minmax(0, 2fr) minmax(0, 3fr);
  min-height: 0;
  padding-bottom: 2rem;
}

.layout-column {
  min-height: 0;
  overflow-y: auto;
}

.layout-column > .card:first-child {
  margin-top: 0;
}

.eyebrow {
  margin: 0 0 0.5rem;
  color: #b44b2d;
  font:
    700 0.75rem/1.2 ui-monospace,
    SFMono-Regular,
    Consolas,
    monospace;
  letter-spacing: 0.12em;
}

h1,
h2,
h3 {
  margin-top: 0;
}
h1 {
  max-width: none;
  margin-bottom: 0.75rem;
  font-size: clamp(1.9rem, 4.6vw, 3.2rem);
  line-height: 1.05;
  text-wrap: balance;
}
h2 {
  font-size: 1.45rem;
}
h3 {
  font-size: 1rem;
}

.card {
  margin: 1rem 0;
  padding: 1.35rem;
  border: 1px solid #cad6d1;
  border-radius: 8px;
  background: #fbfcfa;
  box-shadow: 0 10px 30px rgba(28, 48, 46, 0.06);
}

.grid {
  display: grid;
  gap: 1rem;
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
label {
  display: grid;
  gap: 0.35rem;
  color: #53616b;
  font:
    700 0.8rem ui-monospace,
    SFMono-Regular,
    Consolas,
    monospace;
}
input,
textarea {
  width: 100%;
  padding: 0.7rem 0.8rem;
  border: 1px solid #b8c8c1;
  border-radius: 4px;
  color: inherit;
  background: white;
  font:
    1rem Georgia,
    serif;
}
/* The props textarea holds JSON: monospace keeps braces and indentation
   legible, and vertical-only resize preserves the label grid's column
   alignment. */
textarea {
  font:
    0.85rem/1.5 ui-monospace,
    SFMono-Regular,
    Consolas,
    monospace;
  resize: vertical;
}

.storage-options {
  display: grid;
  gap: 1rem;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  align-items: center;
  /* Extra breathing room before the Config sync interval field, matching
     the 1.25rem vertical rhythm used by .actions and .hint. */
  margin-bottom: 1.25rem;
}
#database-name-field.disabled {
  opacity: 0.55;
}

#config-sync-interval-field {
  max-width: 24rem;
}

/* Lifecycle controls as a single-column grid: one row per button, every
   button in a shared max-content column (the widest label sets it, so all
   five left-align) and every custom-ID input in column two. Rows are
   wrappers whose cells join the outer tracks via subgrid; stop rows simply
   leave column two empty. */
.api-grid {
  display: grid;
  grid-template-columns: max-content minmax(0, 1fr);
  row-gap: 0.65rem;
}
.api-grid .api-row {
  display: grid;
  grid-column: 1 / -1;
  grid-template-columns: subgrid;
  column-gap: 0.65rem;
}
/* All three custom-ID inputs share one length rule with the tab payload
   inputs: the payload basis (80% of the card width minus the 6rem label
   column+gap; cqi resolves against the .api-card size container) stretched
   by 1.4, under a 42rem ceiling (30rem x 1.4). Sharing the rule keeps
   session/tracking exactly as long as instanceId — and as the tab fields —
   at every width; the 100% clamp absorbs narrow cards into the grid column
   instead of overflowing it. */
.api-grid input {
  width: calc(1.4 * (80cqi - 4.8rem));
  max-width: min(42rem, 100%);
}
/* Size container for the cqi-based input length: 100cqi = this card's
   content width, the same basis the tab payload inputs resolve against. */
.api-card {
  container-type: inline-size;
}

/* Stacked lifecycle readout: instanceId / sessionId / trackingId, one per
   line. The generated session/tracking IDs are long enough that a single
   row ran past the card edge. */
.lifecycle-state {
  display: grid;
  gap: 0.3rem;
  margin-top: 1.25rem;
}
.lifecycle-state .effective {
  margin: 0;
}

/* ELMA API tabs: Logger / Analytics, one visible panel at a time. The tab
   bar sits below the shared lifecycle rows, hence the top margin. */
.tab-bar {
  display: flex;
  gap: 0.35rem;
  margin: 1.5rem 0 1.25rem;
  border-bottom: 1px solid #cad6d1;
}
.tab-bar .tab {
  margin-bottom: -1px;
  padding: 0.55rem 1.1rem;
  border: 1px solid transparent;
  border-radius: 4px 4px 0 0;
  color: #53616b;
  background: none;
  /* Larger than the regular 0.8rem button font so the tab names stand out. */
  font-size: 0.95rem;
  letter-spacing: 0.03em;
}
.tab-bar .tab:hover {
  color: #1d6b62;
  background: #dcebe5;
}
.tab-bar .tab.active {
  border-color: #cad6d1;
  border-bottom-color: #fbfcfa;
  color: #1d6b62;
  background: #fbfcfa;
}
.tab-panel {
  display: grid;
  gap: 1rem;
}
/* The class rule above would beat the UA `[hidden] { display: none }`. */
.tab-panel[hidden] {
  display: none;
}
/* Tab section headings (Log configuration / Analytics configuration): same
   style as the Environment heading in the Setup card (.override-group h3). */
.tab-panel h3 {
  margin: 0;
  color: #b44b2d;
  font:
    700 0.75rem/1.2 ui-monospace,
    SFMono-Regular,
    Consolas,
    monospace;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}
.tab-panel .actions {
  margin-top: 0;
}
/* Tab configuration sections: one column per feature group (Logger: log
   level | logging; Analytics: tracking | IP sharing). Methods stay one per
   row, but the paired columns fill the card width instead of leaving most
   of every row empty. Row gap matches the in-row `.actions` gap so all
   buttons sit on one vertical rhythm. */
.config-columns {
  display: grid;
  /* Content-sized columns anchored left: the second group always sits a
     fixed gap after the first. Equal 1fr columns would start group two at
     the card's midpoint, drifting the groups apart on wide screens. */
  grid-template-columns: repeat(2, auto);
  justify-content: start;
  column-gap: 6rem;
}
.config-group {
  display: grid;
  gap: 0.65rem;
  align-content: start;
}
/* Tab payload grids (Logger / Analytics): payload fields stack in a single
   column instead of sitting side by side. */
.tab-panel .grid {
  grid-template-columns: 1fr;
}
/* Tab payload labels (Logger / Analytics): label text and input on the same
   line. The label column is a shared fixed width — sized for the longest
   Analytics label, "Props (JSON)" — so every input starts at the same x and
   runs to the same right edge. */
.tab-panel label.inline {
  grid-template-columns: 5.5rem 1fr;
  align-items: center;
  gap: 0.5rem;
}
/* All payload fields start at the same x (shared label column) and share
   the lifecycle inputs' length rule (see .api-grid input): the 80% basis
   stretched by 1.4 under a 42rem ceiling, so they end at the same x too —
   full panel width looked overly long. The 100% clamp keeps them inside
   the label grid's field column on narrow cards. */
.tab-panel label.inline input,
.tab-panel label.inline textarea {
  width: calc(1.4 * (80cqi - 4.8rem));
  max-width: min(42rem, 100%);
}
/* The multi-line props field tops out its row: the shared center alignment
   would float the label text at mid-textarea height. */
.tab-panel label.inline:has(textarea) {
  align-items: start;
}
/* Click-time props validation: a failed JSON parse marks the input with a
   red border and prints the message right below it (column 2 keeps it
   aligned with the input); editing the field clears both. */
.tab-panel input.invalid,
.tab-panel textarea.invalid {
  border-color: #a3291b;
}
.tab-panel .field-error {
  grid-column: 2;
  color: #a3291b;
  font:
    400 0.75rem/1.4 ui-monospace,
    SFMono-Regular,
    Consolas,
    monospace;
}
/* Divider separating each tab's API buttons from its own tag/message
   payload inputs; matches the border color used by the tab bar and cards. */
.tab-panel hr {
  margin: 0.25rem 0;
  border: 0;
  border-top: 1px solid #cad6d1;
}
/* The global `select { width: 100% }` is meant for form grids; inside the
   flex `.actions` row the level dropdown sits next to its button instead. */
.tab-panel .actions select {
  width: auto;
  min-width: 6.4rem; /* ~80% of the previous 8rem floor */
}
/* Getter results sit inline next to their button, vertically centered. The
   min-width reserves room for the value so the row does not shift when the
   output goes from blank to populated. */
.tab-panel .actions .effective {
  align-self: center;
  min-width: 3.5rem;
  margin: 0;
}

.radio-group {
  display: grid;
  gap: 0.35rem;
  color: #53616b;
  font:
    700 0.8rem ui-monospace,
    SFMono-Regular,
    Consolas,
    monospace;
}
.radio-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem 1.5rem;
  align-items: center;
}
/* Inline sub-setting of a radio option (e.g. Database name for IndexedDB):
   compact input sitting right after its radio in the same row. The basis
   hugs the input (was 14rem with a 64%-wide input, which left ~5rem of
   dead space before the Memory radio). */
.radio-subfield {
  flex: 0 1 9.5rem;
  min-width: 0;
}
.radio-subfield input {
  padding: 0.45rem 0.6rem;
  font-size: 0.85rem;
}
label.radio {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}
label.radio input[type='radio'] {
  width: 1.05rem;
  height: 1.05rem;
  accent-color: #1d6b62;
}

.override-group {
  display: grid;
  gap: 1rem;
  align-content: start;
}
.override-group h3 {
  margin: 0;
  color: #b44b2d;
  font:
    700 0.75rem/1.2 ui-monospace,
    SFMono-Regular,
    Consolas,
    monospace;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}
.override-group .hint {
  margin: 0;
}
.override-group .actions {
  margin-top: 0;
}
.override-group .effective {
  margin: 0;
  overflow-wrap: anywhere;
}

.env-group {
  max-width: 24rem;
  margin-bottom: 1.25rem;
}

/* Client secret: masked input with an inline show/hide eye toggle. */
.password-field {
  position: relative;
  display: flex;
}
.password-field input {
  padding-right: 2.6rem;
}
.password-toggle {
  position: absolute;
  top: 50%;
  right: 0.4rem;
  display: flex;
  align-items: center;
  padding: 0.3rem;
  border-radius: 4px;
  color: #53616b;
  background: none;
  transform: translateY(-50%);
}
.password-toggle:hover {
  color: #1d6b62;
  background: none;
}
.password-toggle svg {
  display: none;
}
.password-toggle[aria-pressed='false'] .icon-eye {
  display: block;
}
.password-toggle[aria-pressed='true'] .icon-eye-off {
  display: block;
}

.config-panel {
  margin-top: 1.25rem;
  padding-top: 1.25rem;
  border-top: 1px solid #cad6d1;
}
.config-panel h3 {
  margin: 0 0 0.5rem;
  color: #b44b2d;
  font:
    700 0.75rem/1.2 ui-monospace,
    SFMono-Regular,
    Consolas,
    monospace;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}
.config-panel .hint {
  margin: 0;
}
.config-groups {
  display: grid;
  gap: 1rem;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  margin-top: 1rem;
}
/* The class rule above would beat the UA `[hidden] { display: none }`. */
.config-groups[hidden] {
  display: none;
}
.config-groups h4 {
  margin: 0 0 0.5rem;
  color: #53616b;
  font:
    700 0.75rem ui-monospace,
    SFMono-Regular,
    Consolas,
    monospace;
  letter-spacing: 0.08em;
}
.config-groups dl {
  margin: 0;
  padding: 0.75rem 1rem;
  border-radius: 4px;
  color: #dcebe5;
  background: #182b2b;
  font:
    0.75rem/1.7 ui-monospace,
    SFMono-Regular,
    Consolas,
    monospace;
}
.config-groups dl > div {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
}
.config-groups dt {
  color: #9fb9b2;
}
.config-groups dd {
  margin: 0;
  font-weight: 700;
  text-align: right;
  overflow-wrap: anywhere;
}

select {
  width: 100%;
  padding: 0.7rem 0.8rem;
  border: 1px solid #b8c8c1;
  border-radius: 4px;
  color: inherit;
  background: white;
  font:
    1rem Georgia,
    serif;
}
select:disabled {
  color: #687a73;
  background: #edf2f0;
  cursor: not-allowed;
}

.hint {
  margin: 0 0 1.25rem;
  color: #53616b;
  font-size: 0.88rem;
}
.effective {
  margin: 1.25rem 0 0;
  color: #1d6b62;
  font:
    0.8rem ui-monospace,
    SFMono-Regular,
    Consolas,
    monospace;
}

.actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.65rem;
  margin-top: 1.25rem;
}
button {
  padding: 0.7rem 1rem;
  border: 0;
  border-radius: 4px;
  color: white;
  background: #1d6b62;
  cursor: pointer;
  font:
    700 0.8rem ui-monospace,
    SFMono-Regular,
    Consolas,
    monospace;
}
button:hover {
  background: #155249;
}
button:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}
button:disabled:hover {
  background: #1d6b62;
}
button.secondary:disabled:hover {
  background: #dcebe5;
}
input:disabled {
  color: #687a73;
  background: #edf2f0;
  cursor: not-allowed;
}
button.secondary {
  color: #1d6b62;
  background: #dcebe5;
}
/* Universal click acknowledgment: a brief darkening flash on every button
   press, so clicks whose effect is invisible nearby (repeat getters,
   records the SDK filters out) still respond at the pointer. app.js adds
   the class on click; animationend removes it. brightness() works across
   all button colors (teal / secondary / tabs). */
@keyframes button-pulse {
  0% {
    filter: brightness(1);
  }
  35% {
    filter: brightness(0.75);
  }
  100% {
    filter: brightness(1);
  }
}
button.pulse {
  animation: button-pulse 250ms ease-out;
}

.output-heading {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
}
.output-card .actions {
  margin: 0 0 1.25rem;
}
.output-grid h3.not-inspectable {
  color: #b44b2d;
}
#status {
  margin: -0.5rem 0 1.25rem;
  color: #53616b;
}
#status.error {
  color: #a3291b;
}
.output-grid {
  display: grid;
  gap: 1rem;
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
pre {
  min-height: 150px;
  max-height: 420px;
  overflow: auto;
  margin: 0;
  padding: 1rem;
  border-radius: 4px;
  color: #dcebe5;
  background: #182b2b;
  font:
    0.75rem/1.5 ui-monospace,
    SFMono-Regular,
    Consolas,
    monospace;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

@media (max-width: 680px) {
  body {
    overflow: auto;
  }
  main {
    height: auto;
    padding: 2rem 1rem 0;
  }
  .layout {
    grid-template-columns: 1fr;
    padding-bottom: 2rem;
  }
  .layout-column {
    overflow-y: visible;
  }
  .grid,
  .output-grid,
  .storage-options,
  .config-columns,
  .config-groups {
    grid-template-columns: 1fr;
  }
}
