/* ABOUTME: The whole app's stylesheet — admin chrome, tables, forms, and the */
/* ABOUTME: customer-facing sign-in/consent/denial cards. Plain CSS, no build step. */

/*
 * Every layout loads styles with `stylesheet_link_tag :app`, which bulk-includes
 * app/assets/ CSS sorted by logical path — so splitting this into several files
 * would make the cascade depend on their filenames. One file keeps the order
 * explicit; the section comments below are the organization.
 */

/* ---------------------------------------------------------------- Palette -- */

:root {
  --font-sans: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --font-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace;

  --bg: #faf7f2;
  --surface: #fffefb;
  --surface-sunken: #f1ece3;
  --border: #e3dbcd;
  --border-strong: #cbc0ad;
  --text: #2b2723;
  --text-muted: #6d6459;

  --accent: #0d7d76;
  --accent-hover: #0a625d;
  --accent-border: #b9dbd7;
  --accent-soft: #e3f1ef;
  --accent-ink: #0a4f4b;

  --danger: #a8341c;
  --danger-hover: #8b2a17;
  --danger-border: #e8c4b8;
  --danger-soft: #fbeae5;

  --radius: 8px;
  --radius-sm: 4px;
  --shadow-card: 0 1px 2px rgba(43, 39, 35, 0.06), 0 10px 30px rgba(43, 39, 35, 0.07);

  --content-width: 64rem;
  --gutter: 1.5rem;
}

/* -------------------------------------------------------------- Normalize -- */

*,
*::before,
*::after {
  box-sizing: border-box;
}

body,
h1,
h2,
h3,
p,
ul,
fieldset,
legend {
  margin: 0;
  padding: 0;
}

ul {
  list-style: none;
}

button,
input,
select,
textarea {
  font: inherit;
  color: inherit;
}

table {
  border-collapse: collapse;
}

/* ------------------------------------------------------------------- Base -- */

html {
  -webkit-text-size-adjust: 100%;
}

body {
  font-family: var(--font-sans);
  font-size: 1rem;
  line-height: 1.55;
  color: var(--text);
  background: var(--bg);
}

h1 {
  font-size: 1.5rem;
  font-weight: 600;
  letter-spacing: -0.015em;
}

h2 {
  font-size: 1.0625rem;
  font-weight: 600;
}

a {
  color: var(--accent-hover);
  text-decoration: underline;
  text-underline-offset: 2px;
}

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

code {
  font-family: var(--font-mono);
  font-size: 0.875em;
  background: var(--surface-sunken);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 0.125rem 0.375rem;
  overflow-wrap: anywhere;
}

a:focus-visible,
button:focus-visible,
input[type="submit"]:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* ------------------------------------------------------------ Admin shell -- */

.admin-nav {
  background: var(--surface);
  border-bottom: 1px solid var(--border);
}

.admin-nav-inner {
  display: flex;
  align-items: center;
  gap: 1.5rem;
  max-width: var(--content-width);
  margin: 0 auto;
  padding: 0.75rem var(--gutter);
}

.admin-nav-brand {
  font-size: 1.0625rem;
  font-weight: 650;
  letter-spacing: -0.015em;
  color: var(--text);
  text-decoration: none;
}

.admin-nav nav {
  flex: 1;
}

.admin-nav nav ul {
  display: flex;
  gap: 0.25rem;
}

.admin-nav nav a {
  display: block;
  padding: 0.375rem 0.75rem;
  border-radius: var(--radius-sm);
  color: var(--text-muted);
  font-weight: 500;
  text-decoration: none;
}

.admin-nav nav a:hover {
  background: var(--surface-sunken);
  color: var(--text);
}

main {
  max-width: var(--content-width);
  margin: 0 auto;
  padding: 2rem var(--gutter) 4rem;
}

/* Vertical rhythm for page-level and fieldset-level blocks, so no view has to
   carry spacing markup of its own. */
main > * + *,
fieldset > * + * {
  margin-top: 1.25rem;
}

main p,
fieldset p {
  color: var(--text-muted);
}

/* ----------------------------------------------------------------- Flash -- */

.flash,
.field-errors,
.alert {
  padding: 0.75rem 1rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  font-size: 0.9375rem;
}

/* Flash sits outside %main, so it lines itself up with main's content column. */
.flash {
  width: calc(100% - var(--gutter) * 2);
  max-width: calc(var(--content-width) - var(--gutter) * 2);
  margin: 1.25rem auto 0;
}

.flash-notice {
  background: var(--accent-soft);
  border-color: var(--accent-border);
  color: var(--accent-ink);
}

.flash-alert,
.field-errors,
.alert {
  background: var(--danger-soft);
  border-color: var(--danger-border);
  color: var(--danger);
}

.flash p,
.field-errors p {
  margin: 0;
  color: inherit;
}

.flash code {
  display: block;
  margin-top: 0.5rem;
  background: var(--surface);
  color: var(--text);
}

.field-errors ul {
  list-style: disc;
  padding-left: 1.25rem;
}

/* ---------------------------------------------------------------- Tables -- */

table {
  width: 100%;
  background: var(--surface);
  border: 1px solid var(--border);
  font-size: 0.9375rem;
}

thead th {
  padding: 0.5rem 0.75rem;
  background: var(--surface-sunken);
  border-bottom: 1px solid var(--border);
  text-align: left;
  font-size: 0.75rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-muted);
}

td {
  padding: 0.625rem 0.75rem;
  border-bottom: 1px solid var(--border);
  vertical-align: middle;
  overflow-wrap: break-word;
}

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

td a + a {
  margin-left: 0.75rem;
}

/* --------------------------------------------------------------- Buttons -- */

button,
input[type="submit"],
.btn-primary,
.btn-secondary,
.btn-danger {
  display: inline-block;
  padding: 0.5rem 1rem;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--text);
  font-size: 0.9375rem;
  font-weight: 550;
  line-height: 1.3;
  text-align: center;
  text-decoration: none;
  cursor: pointer;
}

button:hover,
.btn-secondary:hover {
  background: var(--surface-sunken);
}

/* A form's submit is always that form's affirmative action, so it reads as the
   call to action whether or not the view bothered to add a class. */
input[type="submit"],
.btn-primary {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
}

input[type="submit"]:hover,
.btn-primary:hover {
  background: var(--accent-hover);
  border-color: var(--accent-hover);
  color: #fff;
}

.btn-danger {
  background: var(--danger);
  border-color: var(--danger);
  color: #fff;
}

.btn-danger:hover {
  background: var(--danger-hover);
  border-color: var(--danger-hover);
  color: #fff;
}

/* button_to wraps every button in its own form; inline-block keeps them beside
   whatever they sit next to instead of each claiming a whole row. */
.button_to {
  display: inline-block;
  margin: 0;
}

td button,
td input[type="submit"] {
  padding: 0.3125rem 0.625rem;
  font-size: 0.8125rem;
}

/* ----------------------------------------------------------------- Forms -- */

.field {
  margin-bottom: 0.75rem;
}

.field label {
  display: block;
  margin-bottom: 0.3125rem;
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  color: var(--text-muted);
}

input[type="text"],
input[type="email"],
input[type="password"],
select,
textarea {
  width: 100%;
  max-width: 32rem;
  padding: 0.5rem 0.625rem;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--text);
}

input[type="text"]:focus,
input[type="email"]:focus,
input[type="password"]:focus,
select:focus,
textarea:focus {
  border-color: var(--accent);
  outline: none;
  box-shadow: 0 0 0 3px var(--accent-soft);
}

/* Keeps a form's submit under its textarea rather than beside it. */
textarea {
  display: block;
}

textarea + input[type="submit"] {
  margin-top: 0.75rem;
}

input[type="checkbox"] {
  accent-color: var(--accent);
}

/* Checkbox labels follow their input, so they stay on its line. */
input[type="checkbox"] + label {
  display: inline;
  margin: 0 0 0 0.375rem;
  font-size: 0.9375rem;
  font-weight: 500;
  color: var(--text);
}

fieldset {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1.25rem;
}

legend {
  padding: 0 0.5rem;
  font-size: 0.8125rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-muted);
}

/* Status pills: allowlist entry kinds, and the write-only secret's set/not-set. */
.allowlist-kind,
.secret-indicator {
  display: inline-block;
  padding: 0.125rem 0.5rem;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface-sunken);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--text-muted);
}

/* The set/not-set pill precedes its input in the markup, so it takes a line of
   its own instead of shunting the input out of the column. */
.secret-indicator {
  display: block;
  width: fit-content;
  margin-bottom: 0.3125rem;
}

.allowlist-row {
  display: flex;
  align-items: center;
  gap: 0.625rem;
  margin-bottom: 0.5rem;
  padding: 0.5rem 0.75rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  font-size: 0.9375rem;
}

.allowlist-value {
  font-family: var(--font-mono);
}

.allowlist-row label {
  margin-left: auto;
  font-size: 0.8125rem;
  color: var(--text-muted);
}

/* ----------------------------------------------------------- Danger zone -- */

fieldset.danger-zone {
  background: var(--danger-soft);
  border-color: var(--danger-border);
}

fieldset.danger-zone legend,
fieldset.danger-zone a,
fieldset.danger-zone p {
  color: var(--danger);
}

fieldset.danger-zone button {
  border-color: var(--danger);
  color: var(--danger);
}

fieldset.danger-zone button:hover {
  background: var(--danger);
  color: #fff;
}

/* --------------------------------------------------- Credentials (CUJ-2) -- */

.credential-tabs {
  border-bottom: 1px solid var(--border);
}

.credential-tabs ul {
  display: flex;
  gap: 0.25rem;
}

.credential-tabs li {
  margin-bottom: -1px;
}

.credential-tabs a,
.credential-tabs strong {
  display: block;
  padding: 0.5rem 0.875rem;
  border: 1px solid transparent;
  border-bottom: 0;
  border-radius: var(--radius-sm) var(--radius-sm) 0 0;
  font-size: 0.9375rem;
  font-weight: 550;
  color: var(--text-muted);
  text-decoration: none;
}

.credential-tabs a:hover {
  background: var(--surface-sunken);
  color: var(--text);
}

/* The current tab is a <strong>; its own bottom edge joins it to the page. */
.credential-tabs strong {
  background: var(--surface);
  border-color: var(--border);
  box-shadow: 0 1px 0 var(--surface);
  color: var(--text);
}

.credential-fields {
  display: grid;
  gap: 0.875rem;
}

.credential-fields .field {
  margin: 0;
}

/* Read-only credential values: monospace and wide, so a whole URL or secret can
   be selected and copied without scrolling the field. */
.credential-fields input[readonly] {
  max-width: 44rem;
  font-family: var(--font-mono);
  font-size: 0.875rem;
  background: var(--surface-sunken);
  cursor: text;
}

.client-guidance {
  padding: 0.875rem 1rem;
  background: var(--accent-soft);
  border: 1px solid var(--accent-border);
  border-left: 3px solid var(--accent);
  border-radius: var(--radius-sm);
  font-size: 0.9375rem;
}

.client-guidance p {
  margin: 0;
  color: var(--accent-ink);
}

.client-guidance p + p {
  margin-top: 0.5rem;
}

/* ------------------------------- End-user sign-in, consent, denial cards -- */

.end-user-auth {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 100vh;
  padding: 2rem 1.25rem;
}

.end-user-auth-card {
  width: 100%;
  max-width: 27rem;
  padding: 2rem 1.75rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
  box-shadow: var(--shadow-card);
  text-align: center;
}

.end-user-auth-card > * + * {
  margin-top: 1rem;
}

.auth-brand {
  font-size: 0.8125rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent);
}

.end-user-auth-card h1 {
  font-size: 1.25rem;
}

.end-user-auth-card p {
  font-size: 0.9375rem;
  color: var(--text-muted);
}

.end-user-auth-card strong {
  font-weight: 650;
  color: var(--text);
}

.end-user-auth-card .button_to {
  margin-top: 1.5rem;
}

.end-user-auth-card .button_to + .button_to {
  margin-left: 0.5rem;
}

/* Allow is the affirmative choice and carries the weight; Deny stays a quiet
   outline at the same size, so the pair reads as one decision. */
.end-user-auth-card .btn-primary,
.end-user-auth-card .btn-secondary {
  padding: 0.625rem 1.5rem;
  font-size: 1rem;
}

.end-user-auth-card .btn-secondary {
  border-color: var(--border);
  color: var(--text-muted);
}

/* ----------------------------------------------------------- Narrow view -- */

/* -------------------------------------------- Backend auth mode disclosure -- */

/* Only the selected mode's fields are shown, with no JavaScript: this app ships
   none, and :has() + option:checked track the select live. Gated on :has()
   support so a browser without it shows every mode's fields instead of hiding
   them all, which is usable rather than broken. Hidden inputs still submit —
   Proxy#clear_unused_auth_config is what makes that harmless. */
@supports selector(:has(*)) {
  .auth-mode-fields {
    display: none;
  }

  form:has(#proxy_backend_auth_mode option[value="none"]:checked) .auth-mode-fields--none,
  form:has(#proxy_backend_auth_mode option[value="static_header"]:checked) .auth-mode-fields--static-header,
  form:has(#proxy_backend_auth_mode option[value="gcp_iap_service_account"]:checked) .auth-mode-fields--gcp-iap {
    display: block;
  }
}

@media (max-width: 40rem) {
  .admin-nav-inner {
    flex-wrap: wrap;
    gap: 0.75rem;
  }

  main {
    padding: 1.5rem 1rem 3rem;
  }

  input[type="text"],
  input[type="email"],
  input[type="password"],
  select,
  textarea {
    max-width: 100%;
  }
}
