/* ===========================================================================
   CERENA portal theme — Phase 7.6 rebrand.
   Palette + typography aligned with the live cerena.pt brand (verified
   2026-08-22 by extracting computed styles from https://cerena.pt): white
   #FFFFFF surface, gray #808080 secondary chrome, IST navy #232C65 for primary
   headings/links, glacier #1F4E66 secondary. Typography: **Titillium Web for
   body AND headings** — the live site is all-Titillium (verified: body + h2
   both "Titillium Web", sans-serif). Inter was an earlier assumption, dropped.

   Deliberate divergence from the live brand: body text color is #2A2A2A
   (--ink, near-black), NOT the live site's #808080 gray. The live gray-on-
   white at 14px is 3.95:1 — below AA's 4.5:1 for body text. The portal is an
   auth surface; readability wins. The gray #808080 stays as --ink-soft for
   nav/secondary chrome (where AA-large rules apply, the brand's gray passes).

   Back-compat: the Phase 7.3 cream/copper token names (--paper, --aurora, etc.)
   are kept as ALIASES pointing at the new palette, so the component classes
   below (written against the old names) keep rendering on the new theme without
   a per-rule rewrite. `var(--aurora)` in templates (api_keys.html) resolves to
   the IST navy primary now.
   ========================================================================== */

:root {
  /* ---- Phase 7.6 brand palette (the source of truth) ---- */
  --paper: #FFFFFF;          /* page surface — white (was cream #F4EFE3) */
  --paper-2: #F4F5F7;        /* subtle alt row / hover (was #ECE5D2) */
  --ink: #2A2A2A;            /* body text — near-black (was #1B201D) */
  --ink-soft: #808080;       /* secondary text — gray (matches live cerena.pt body) */
  --rule: #E1E3E8;           /* hairline borders (was warm #C9C2B0) */

  /* brand accents */
  --ist-navy: #232C65;       /* primary — IST navy (live cerena.pt headings/links) */
  --glacier: #1F4E66;        /* secondary — glacier blue */

  /* semantic tokens — AA-contrast-checked on white */
  --success: #1E6B3A;        /* green (>= 4.5:1 on #FFF) */
  --error:   #8A2A1F;        /* deep terracotta (>= 4.5:1 on #FFF) */
  --warn:    #7A4A1A;        /* dark copper (>= 4.5:1 on #FFF) */
  --info:    var(--glacier);
  --link:    var(--ist-navy);
  --link-hover: #1A2350;     /* navy 10% darker */

  /* focus ring — visible at 3:1 on white + navy for WCAG 2.4.7 + 1.4.11 */
  --focus: #1F4E66;

  /* surface elevation (flat on white) */
  --surface: #FFFFFF;
  --surface-2: #F4F5F7;
  --surface-border: var(--rule);

  /* radii + shadows — flat */
  --radius: 4px;
  --radius-lg: 8px;
  --shadow-sm: 0 1px 2px rgba(35, 44, 101, 0.06);
  --shadow-md: 0 4px 12px rgba(35, 44, 101, 0.08);

  /* ---- Back-compat aliases (Phase 7.3 names → Phase 7.6 palette) ----
     Kept so the component classes below, written against the old names, keep
     rendering on the new theme. Templates that reference var(--aurora)
     (api_keys.html) resolve to the IST navy primary. Safe to remove once the
     component CSS is rewritten against the new names. */
  --aurora: var(--ist-navy);   /* copper → IST navy (primary action) */
  --strata: var(--glacier);    /* terracotta → glacier (secondary) */
  --carto:  var(--glacier);    /* glacier stays glacier */
}

* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
html { scroll-behavior: smooth; }

body {
  background: var(--paper);
  color: var(--ink);
  font-family: 'Titillium Web', system-ui, -apple-system, sans-serif;
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  /* drop the cream radial-gradient tint — flat white now */
}

a { color: var(--link); text-decoration: underline; text-underline-offset: 2px; }
a:hover { color: var(--link-hover); }
a:focus-visible, button:focus-visible, input:focus-visible, select:focus-visible, textarea:focus-visible {
  outline: 3px solid var(--focus);
  outline-offset: 2px;
  border-radius: 2px;
}

/* --- Layout ----------------------------------------------------------- */
.container {
  max-width: 920px;       /* narrower than cerena-site (1280) — a portal, not a marketing page */
  margin: 0 auto;
  padding: 0 28px;
}
.container-narrow { max-width: 560px; }

/* --- Masthead (site header) ------------------------------------------ */
.masthead {
  padding: 28px 0 20px;
  border-bottom: 1px solid var(--rule);
}
/* The CERENA logo image (official asset, 1024×275 PNG) — sized to a header-appropriate height with the aspect ratio preserved. The .brand-link wrapper is the home-page anchor around it. */
.brand-logo {
  display: block;
  height: 44px;
  width: auto;
  max-width: 100%;
}
.brand-link:hover .brand-logo { opacity: 0.85; }
/* Landing-page hero h1 (the body section .masthead h1 — distinct from the site header's logo). */
.masthead h1, .masthead .brand-title {
  font-family: 'Titillium Web', system-ui, sans-serif;
  font-weight: 900;
  font-size: clamp(28px, 4vw, 40px);
  line-height: 1.05;
  letter-spacing: -0.02em;
  margin: 0;
}
.masthead h1 em, .brand-title em {
  font-style: italic;
  font-weight: 400;
  color: var(--aurora);
}
.masthead .nav {
  display: flex;
  flex-wrap: wrap;        /* allow the nav links to wrap on narrow viewports instead of overflowing horizontally */
  gap: 14px 18px;         /* row-gap smaller so wrapped rows stay tight; column-gap unchanged */
  margin-top: 14px;
  font-size: 14px;
}
.masthead .nav a { text-decoration: none; color: var(--ink-soft); }
.masthead .nav a:hover { color: var(--aurora); }
.masthead .nav .spacer { flex: 1; }

/* --- Page sections --------------------------------------------------- */
/* `section` padding is intentionally modest (20px top/bottom) so a typical
   form page (h1 + lede + panel) fits within the desktop viewport without a
   vertical scrollbar — measured at 1440×900: masthead 138 + section 634 +
   footer-margin 48 + footer 90 = 910px, 10px over the viewport. Reducing the
   section padding + footer margin clears that overflow with headroom. */
section { padding: 20px 0; }
.section-narrow {
  /* A centered narrow column for form pages: constrains h1 + lede + the
     centered .panel-narrow card to the SAME width so the heading/description
     aligns with the card (was left-aligned in the 920px .container while the
     panel sat centered — a visible inconsistency vs. the auth pages, where
     everything is full-width and consistent). max-width matches .panel-narrow
     (480px) + margin:auto centers the whole block. */
  max-width: 480px;
  margin-left: auto;
  margin-right: auto;
}
.section-narrow h1,
.section-narrow .lede { text-align: center; }
/* The trailing register/"no account?" line under the panel reads better
   centered too (it sits inside the same narrow column). */
.section-narrow > p:last-of-type { text-align: center; }
.section-eyebrow {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 11px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin: 0 0 14px;
}
h1 {
  font-family: 'Titillium Web', system-ui, sans-serif;
  font-weight: 700;
  font-size: clamp(24px, 2.8vw, 30px);
  line-height: 1.15;
  letter-spacing: -0.01em;
  margin: 0 0 12px;
}
h2 {
  font-family: 'Titillium Web', system-ui, sans-serif;
  font-weight: 700;
  font-size: clamp(22px, 2.6vw, 28px);
  line-height: 1.15;
  letter-spacing: -0.01em;
  margin: 0 0 16px;
}
h3 {
  font-family: 'Titillium Web', system-ui, sans-serif;
  font-weight: 700;
  font-size: 19px;
  margin: 0 0 10px;
}
.lede {
  font-family: 'Titillium Web', system-ui, sans-serif;
  font-size: clamp(17px, 1.5vw, 20px);
  line-height: 1.55;
  max-width: 60ch;
  color: var(--ink-soft);
  margin: 0 0 24px;
}
p { margin: 0 0 12px; }

/* --- Landing hero — centered brand card (b-U #3, Phase 7.6.4) ---------
   The IDP hosted-login pattern: a full-viewport-height section that centers
   a single brand card vertically + horizontally. The site header (.masthead
   in base.html) keeps the logo + nav; the BODY hero is this centered card.
   Matches the Entra/Cognito/Auth0 hosted-login visual language (no left-
   aligned top-corner hero, no SaaS-marketing capability billboard). */
.landing-hero {
  /* Center the brand card in the remaining viewport. The subtracted constant
     must cover the real header+footer chrome so the page does NOT exceed the
     viewport (which would force an unwanted vertical scrollbar on desktop
     screens that have room to spare). Measured chrome: masthead ~124px +
     footer ~133px + a safety margin ≈ 281px. ``dvh`` (dynamic viewport height)
     is used with a ``vh`` fallback — dvh accounts for mobile browser UI
     (address bar show/hide) so the hero doesn't jump; vh is the legacy floor. */
  min-height: calc(100vh - 281px);
  min-height: calc(100dvh - 281px);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 48px 28px;
}
.brand-card {
  width: 100%;
  max-width: 520px;
  background: var(--surface);
  border: 1px solid var(--surface-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
  padding: 48px 40px 44px;
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
}
/* The CERENA logo inside the card — larger than the 44px header logo so the
   card has a clear brand anchor. Preserves the 1024×275 aspect ratio. */
.brand-card-logo {
  display: block;
  height: 64px;
  width: auto;
  max-width: 100%;
  margin-bottom: 12px;
}
.brand-card-title {
  font-family: 'Titillium Web', system-ui, sans-serif;
  font-weight: 900;
  font-size: clamp(30px, 4.6vw, 44px);
  line-height: 1.08;
  letter-spacing: -0.02em;
  margin: 0 0 8px;
}
.brand-card-title em {
  font-style: italic;
  font-weight: 400;
  color: var(--ist-navy);
}
/* The lede inside the card — centered, slightly tighter max-width so it
   reads as a single comfortable line group, not a wide column. */
.brand-card-lede {
  max-width: 42ch;
  margin: 0 0 28px;
  text-align: center;
}
.brand-card-actions {
  justify-content: center;
  width: 100%;
}
/* Reduced motion: no layout/transform animations to disable here, but keep
   the section scroll-anchored (no smooth-scroll jump when landing). */
@media (prefers-reduced-motion: reduce) {
  .landing-hero { scroll-behavior: auto; }
}

/* --- Cards + panels -------------------------------------------------- */
.panel {
  background: var(--surface);
  border: 1px solid var(--surface-border);
  border-radius: var(--radius-lg);
  padding: 24px 28px;
  box-shadow: var(--shadow-sm);
}
.panel + .panel { margin-top: 20px; }
/* 2026-09-22 fix: service cards are adjacent .panels inside .services-grid;
   the sibling margin above pushed every card after the first (e.g. the VPN
   card) 20px out of row alignment. The grid gap already spaces them. */
.services-grid > .panel + .panel { margin-top: 0; }
.panel h2 { margin-top: 0; }

/* A narrow panel centered horizontally within the .container column — used by
   the short form pages (login, register, verify, password-forgot, error) so a
   420–560px card reads as "centered" on a wide desktop instead of left-hugging
   the 920px column. The width is capped + auto-margined so the dead space is
   split evenly left/right. (Replaces the ad-hoc inline ``max-width:480px`` /
   ``420px`` / ``560px`` on individual .panel elements — those had no
   ``margin: 0 auto`` so the card sat at the column's left edge.) */
.panel-narrow {
  max-width: 480px;
  margin-left: auto;
  margin-right: auto;
}
.panel-narrow-420 { max-width: 420px; margin-left: auto; margin-right: auto; }
.panel-narrow-560 { max-width: 560px; margin-left: auto; margin-right: auto; }

/* Table horizontal-scroll wrapper — prevents wide tables (API keys, MFA
   factors) from overflowing the .container / viewport on narrow screens. The
   usage page already wraps its table this way inline; this class centralizes
   the pattern so the other table pages can use it without per-page inline CSS. */
.table-scroll { overflow-x: auto; }

/* --- Forms ----------------------------------------------------------- */
form { display: flex; flex-direction: column; gap: 14px; }
.form-row { display: flex; flex-direction: column; gap: 4px; }
.form-row label {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 11px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-soft);
}
/* Phase 7.6.1: the login form groups its email field (and its AD equivalents)
   inside <fieldset id="local-fields"> / <fieldset id="ad-fields"> so login.js
   can toggle them as a unit. Browsers ship a default UA border+padding on
   <fieldset>, which drew an unwanted box around just the email/user input
   (it looked like a stray card-inside-a-card). Reset the fieldset to an
   invisible grouping wrapper — no border, no padding, no margin, no legend
   styling — so it carries semantics (a11y grouping) without any visual chrome.
   The visible card is the parent .panel (the max-width:480px form panel). */
fieldset {
  border: 0;
  margin: 0;
  padding: 0;
  min-width: 0;
}
fieldset legend { display: none; }
/* The login-form fieldsets inherit the form's column gap so the rows stay
   evenly spaced whether they live inside a fieldset or directly under <form>. */
#local-fields, #ad-fields {
  display: flex;
  flex-direction: column;
  gap: 14px;
}
/* Phase 7.6.2: modern browsers honour the HTML [hidden] attribute as
   display:none ONLY if no author CSS sets a display rule. The rule above
   (display:flex on #local-fields/#ad-fields) would otherwise override
   [hidden] + leave the inactive fieldset visible (only its inputs are
   disabled, not its container). This rule makes [hidden] win again, so the
   whole inactive fieldset is removed from layout when login.js sets
   fs.hidden=true. Specificity: an id + attribute beats the bare-id rule. */
#local-fields[hidden], #ad-fields[hidden] { display: none; }
input[type=text], input[type=email], input[type=password], input[type=tel],
input[type=number], select, textarea {
  font-family: 'Titillium Web', system-ui, sans-serif;
  font-size: 15px;
  padding: 9px 12px;
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  background: #fff;
  color: var(--ink);
  width: 100%;
}
input::placeholder { color: #8A8676; }
.field-hint { font-size: 13px; color: var(--ink-soft); }

/* --- Buttons --------------------------------------------------------- */
.btn, .btn-link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  font-family: 'Titillium Web', system-ui, sans-serif;
  font-size: 14px;
  font-weight: 600;
  padding: 10px 18px;
  border-radius: var(--radius);
  border: 1px solid transparent;
  cursor: pointer;
  text-decoration: none;
  line-height: 1.2;
  transition: background 0.12s, border-color 0.12s, color 0.12s;
}
.btn-primary { background: var(--aurora); color: #fff; }
.btn-primary:hover { background: #337ab7; color: #fff; }
.btn-secondary { background: transparent; color: var(--aurora); border-color: var(--aurora); }
.btn-secondary:hover { background: #337ab7; color: #fff; border-color: #337ab7; }
.btn-ghost { background: transparent; color: var(--ink-soft); border-color: var(--rule); }
.btn-ghost:hover { background: #337ab7; color: #fff; border-color: #337ab7; }
.btn-danger { background: var(--error); color: #fff; }
.btn-danger:hover { background: #337ab7; color: #fff; }
.btn:disabled, .btn[aria-disabled="true"] { opacity: 0.5; cursor: not-allowed; }
.btn-row { display: flex; gap: 10px; flex-wrap: wrap; }

/* --- Logout forms (Phase 7.6.5 — /logout 405 fix) --------------------
   /logout is a POST route (logout-CSRF best-effort, reads a CSRF token from
   the form body). The Sign-out affordances in the templates are therefore
   tiny inline <form method="post"> wrappers with a hidden CSRF input + a
   <button>, NOT <a href="/logout"> GET anchors (a GET anchor hit the POST-only
   route + returned 405 Method Not Allowed). These rules make the form render
   inline (no block break) + make the nav Sign-out button look like the text
   nav links around it (button chrome stripped in the nav variant; the .btn
   variant inside a .btn-row keeps its button styling, handled by .btn-*). */
.logout-form { display: inline; margin: 0; padding: 0; }
.logout-form button { font: inherit; }
/* Nav variant: the button renders as a muted text link, matching the .nav
   text links (color: var(--ink-soft); hover: var(--link-hover) via the .nav
   scope). No button background/border — it should be indistinguishable from
   the <a> nav links. */
.logout-form-nav button {
  background: none;
  border: 0;
  padding: 0;
  color: var(--ink-soft);
  text-decoration: none;
  cursor: pointer;
}
.logout-form-nav button:hover { color: var(--link-hover); }
.logout-form-nav button:focus-visible {
  outline: 3px solid var(--focus);
  outline-offset: 2px;
  border-radius: 2px;
}

/* --- Flash messages (aria-live) ------------------------------------- */
.flash {
  padding: 12px 16px;
  border-radius: var(--radius);
  border-left: 4px solid;
  margin-bottom: 16px;
  font-size: 14px;
}
.flash-success { background: #E8EFE5; border-left-color: var(--success); color: var(--success); }
.flash-error   { background: #F5E6E3; border-left-color: var(--error);   color: var(--error); }
.flash-info    { background: #E3ECEF; border-left-color: var(--info);    color: var(--info); }
.flash-warn    { background: #F2E9D9; border-left-color: var(--warn);    color: var(--warn); }

/* --- DEV-MOCK-MFA banner (deployment-only dev indicator) ------------ */
/* Bright orange + diagonally striped so it is impossible to mistake a mocked
   deployment for production. Pinned to the top of the viewport, full-width,
   above the masthead. The text is black on orange (#7A4A1A bg / #1B201D ink =
   >= 7:1 contrast, AAA). The banner is conditional on dev_mock_mfa (base.html)
   — when the flag is off, this rule is dead CSS (~200 bytes). */
.dev-mock-banner {
  position: sticky;
  top: 0;
  z-index: 1000;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 8px 16px;
  background: #7A4A1A;
  background-image: repeating-linear-gradient(
    45deg, rgba(0,0,0,0.08) 0, rgba(0,0,0,0.08) 12px,
    transparent 12px, transparent 24px);
  color: #FFFFFF;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.02em;
  text-align: center;
}
.dev-mock-banner strong { font-weight: 700; }
.dev-mock-banner-icon { font-size: 16px; }
/* The inline hint near a code field. Warn copper on warn-tint background so
   it reads as a companion to the banner without competing with form errors. */
.dev-mock-hint {
  display: block;
  margin-top: 6px;
  padding: 8px 10px;
  background: #F2E9D9;
  border-left: 3px solid var(--warn);
  border-radius: 3px;
  color: var(--warn);
  font-size: 13px;
  font-weight: 500;
}

/* --- Inline error text + help --------------------------------------- */
.field-error { color: var(--error); font-size: 13px; margin-top: 2px; }
.form-error  { color: var(--error); font-size: 14px; font-weight: 500; }
.help-link   { font-size: 13px; color: var(--ink-soft); }

/* --- Code (API keys, backup codes, TOTP secret) ---------------------- */
code, .mono, .code-block {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 13px;
}
.code-block {
  background: var(--surface-2);
  border: 1px solid var(--surface-border);
  border-radius: var(--radius);
  padding: 12px 16px;
  overflow-x: auto;
  white-space: pre-wrap;
  word-break: break-all;
}
.secret-display {
  background: #FFF8E8;
  border: 1px dashed var(--aurora);
  padding: 10px 14px;
  border-radius: var(--radius);
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 13px;
  word-break: break-all;
}

/* --- Tables (API-key list) ------------------------------------------ */
table { width: 100%; border-collapse: collapse; font-size: 14px; }
th, td { text-align: left; padding: 10px 12px; border-bottom: 1px solid var(--rule); }
th { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 11px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--ink-soft); }
tr:last-child td { border-bottom: none; }
.tag { display: inline-block; padding: 2px 8px; border-radius: 999px; font-size: 11px; font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; background: var(--paper-2); color: var(--ink-soft); }
.tag-revoked { background: #F5E6E3; color: var(--error); }
.tag-active { background: #E8EFE5; color: var(--success); }

/* --- Footer --------------------------------------------------------- */
/* b-U #4: two-row institutional footer. Row 1 (footer-affiliation) carries
   the IST institutional mark — CERENA's hosting institution. Row 2
   (footer-portal) carries the portal context + the cerena.pt + Learn-more
   links. The affiliation row is slightly more prominent (IST navy on the
   link) than the muted portal row, matching the academic-research-center
   footer convention (the institution gets the visual weight; the portal is
   the secondary line). */
footer {
  margin-top: 24px;
  padding: 20px 0;
  border-top: 1px solid var(--rule);
  font-size: 13px;
  color: var(--ink-soft);
}
footer a { color: var(--ink-soft); }
footer .footer-affiliation {
  margin-bottom: 6px;
  font-size: 14px;
  color: var(--ink);
}
footer .footer-affiliation-text { color: var(--ink-soft); }
footer .footer-ist-link {
  color: var(--ist-navy);
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 2px;
}
footer .footer-ist-link:hover { color: var(--link-hover); }
footer .footer-portal { font-size: 13px; }

/* --- MFA enrollment helpers ----------------------------------------- */
.totp-secret {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 16px;
  letter-spacing: 0.06em;
  background: var(--surface-2);
  padding: 8px 12px;
  border-radius: var(--radius);
  display: inline-block;
}
.qr img { border: 1px solid var(--rule); border-radius: var(--radius); background: #fff; padding: 8px; }

/* --- Visually-hidden (screen-reader-only) --------------------------- */
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0;
}

/* --- Reduces motion ------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { transition: none !important; animation: none !important; }
}

/* --- Phase 7.6 components (i18n toggle, account-type selector) ------ */

/* Language toggle (PT | EN) in the masthead nav. Visually compact, keyboard-
   reachable (it's two <a>s), indicates the active lang via aria-current. */
.lang-toggle { display: inline-flex; align-items: center; gap: 4px; font-size: 12px; }
.lang-toggle a {
  text-decoration: none; color: var(--ink-soft);
  padding: 2px 6px; border-radius: var(--radius);
  font-weight: 500; letter-spacing: 0.02em;
}
.lang-toggle a:hover { color: var(--ist-navy); }
.lang-toggle a.active { color: var(--ist-navy); background: var(--paper-2); }
.lang-toggle span { color: var(--rule); user-select: none; }

/* Account-type fieldset on the login page (Phase 7.6 Option 3 — informational
   only; both modes submit email+password). */
.account-type {
  border: 1px solid var(--rule); border-radius: var(--radius-lg);
  padding: 14px 16px; margin: 0 0 18px;
}
.account-type legend {
  font-size: 13px; font-weight: 600; color: var(--ink-soft);
  padding: 0 6px; letter-spacing: 0.02em; text-transform: uppercase;
}
.radio-row { display: flex; align-items: center; gap: 8px; padding: 6px 0; }
.radio-row input[type=radio] { accent-color: var(--ist-navy); width: 16px; height: 16px; }
.radio-row span { font-size: 15px; color: var(--ink); }

/* --- Responsive (mobile / narrow viewports) -------------------------- */
/* The portal is structural-first (max-width columns, % widths, clamp() font
   sizes) so most of it reflows without help. These breakpoints close the
   remaining gaps: tighten the .container side padding so content isn't pinned
   to the screen edge on phones, collapse the masthead nav to a tighter wrap,
   and ensure the narrow form panels don't overflow on very small screens. */
@media (max-width: 640px) {
  /* Tighter side gutters on phones — 28px is cramped at 360px viewport width. */
  .container { padding: 0 16px; }
  /* The masthead column gets the tighter padding too (it has its own
     .container). The nav already wraps (flex-wrap above); reduce its gap so a
     wrapped second row sits closer to the first. */
  .masthead { padding: 18px 0 14px; }
  .masthead .nav { gap: 10px 14px; }
  /* Narrow form panels cap at 480/420/560 but on a 360px screen the cap is
     wider than the viewport — let them shrink to the available width (the
     auto margins keep them centered). The .section-narrow column follows the
     same rule so the centered heading block doesn't overflow either. */
  .panel-narrow, .panel-narrow-420, .panel-narrow-560 { max-width: 100%; }
  .section-narrow { max-width: 100%; }
  /* Section padding tightens so a short form fits with less vertical scroll. */
  section { padding: 18px 0; }
  /* The landing hero's 48px padding is too tall on a short phone — reduce so
     the brand card doesn't push the page past the viewport. */
  .landing-hero { padding: 24px 16px; }
  /* Panels shrink their inner padding so the form fields have breathing room
     without the card itself hogging width. */
  .panel { padding: 18px 16px; }
  .brand-card { padding: 32px 24px 28px; }
  /* Tables: ensure they scroll horizontally within the page instead of
     blowing out the .container width. .table-scroll wraps them; this is a
     belt-and-braces rule for any unwrapped table that slips through. */
  table { display: block; overflow-x: auto; white-space: nowrap; }
}

/* Larger phones / small tablets — a middle breakpoint before the 640px fold.
   Only the container gutter + section padding adjust; the layout already
   reflows. */
@media (max-width: 900px) and (min-width: 641px) {
  .container { padding: 0 22px; }
}
.form-hint { font-size: 13px; color: var(--ink-soft); margin: 8px 0 0; }

/* Brand link in the masthead — wraps the CERENA logo image (.brand-logo). The logo is the official CERENA asset (from cerena.pt / the cerena-gpt loading-screen brand set), replacing the earlier text wordmark. */
.brand-link { display: inline-block; }
.brand-link .brand-title { font-family: 'Titillium Web', system-ui, sans-serif; }
.brand-link:hover .brand-title { color: var(--ist-navy); }

/* --- Remember-me checkbox (login form) -------------------------------- */
/* A tight checkbox+label row that sits between the fields and the btn-row.
   Uses a flex row so the box + text align on a single line with a small gap. */
.remember-row { margin: 4px 0 16px; }
.remember-label {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;
  color: var(--ink-soft);
  cursor: pointer;
  user-select: none;
}
.remember-label input[type="checkbox"] {
  width: 16px;
  height: 16px;
  accent-color: var(--ist-navy, #232C65);
  cursor: pointer;
}
.remember-label:hover { color: var(--ink); }

/* --- GDPR cookie banner ----------------------------------------------- */
/* A COMPACT single-row bar (not a fat stacked banner): short message (with a
   collapsible categories <details>) on the left, Accept/Reject buttons on the
   right, both on ONE row at desktop widths. It only stacks when the viewport
   is too narrow to fit the row (CSS flex-wrap + a max-width breakpoint).
   Non-blocking: role=dialog, aria-modal=false — an information+choice surface,
   not a modal wall. z-index above content + flashes. */
.cookie-banner {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 9000;
  background: var(--surface, #fff);
  border-top: 1px solid var(--surface-border, #e4e4e7);
  box-shadow: 0 -4px 16px rgba(0, 0, 0, 0.06);
  padding: 12px 0;
  font-size: 13px;
}
.cookie-banner-inner {
  max-width: 1100px;
  margin: 0 auto;
  padding: 0 28px;
}
/* The main row: text block (flex-grows) + buttons (flex-shrinks). Wraps when
   the buttons no longer fit beside the text. */
.cookie-banner-main {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 16px 24px;
}
.cookie-banner-text {
  flex: 1 1 320px;
  min-width: 0;             /* lets long text wrap, not push buttons off-screen */
}
.cookie-banner-title {
  display: inline;          /* "Cookies" runs inline with the body, no extra row */
  font-size: 14px;
  font-weight: 700;
  margin: 0 8px 0 0;
}
.cookie-banner-body {
  display: inline;
  margin: 0;
  line-height: 1.45;
  color: var(--ink-soft, #555);
  max-width: 70ch;
}
/* Collapsible categories — collapsed by default so it doesn't bloat the bar;
   the visitor can still see exactly what's set, on demand (transparency). */
.cookie-banner-details { display: inline; margin-left: 4px; }
.cookie-banner-details > summary {
  display: inline;
  cursor: pointer;
  font-size: 13px;
  color: var(--ist-navy, #232C65);
  text-decoration: underline;
  list-style: none;          /* hide the default disclosure triangle inline */
}
.cookie-banner-details > summary::-webkit-details-marker { display: none; }
.cookie-banner-details[open] > summary { margin-bottom: 6px; }
.cookie-categories {
  list-style: none;
  margin: 6px 0 0;
  padding: 0;
  display: grid;
  gap: 4px;
  max-width: 60ch;
}
.cookie-categories li { display: grid; gap: 1px; }
.cookie-cat-label { font-weight: 600; font-size: 12px; }
.cookie-cat-desc { color: var(--ink-soft, #555); font-size: 12px; line-height: 1.4; }
/* Buttons: sit at the right of the row on desktop; stay inline until the
   flex-wrap threshold, then the whole .cookie-banner-form wraps below. */
.cookie-banner-form {
  flex: 0 0 auto;
  display: flex;
  gap: 8px;
  align-items: center;
  margin-left: auto;         /* push to the right edge of the row */
}
.cookie-banner-form .btn { min-width: 0; padding: 7px 14px; font-size: 13px; }
.cookie-banner-footer { margin: 6px 0 0; font-size: 12px; }
.cookie-banner-footer a { color: var(--ist-navy, #232C65); text-decoration: underline; }

/* Narrow viewports: the row wraps so the buttons fall under the text (still
   inline+right-aligned, NOT full-width stacked — that's reserved for very
   small phones below). Reject stays as prominent as Accept (same size). */
@media (max-width: 720px) {
  .cookie-banner { padding: 10px 0; }
  .cookie-banner-inner { padding: 0 16px; }
  .cookie-banner-main { gap: 10px; }
  .cookie-banner-text { flex: 1 1 100%; }
  .cookie-banner-form { margin-left: 0; }
}

/* Phones: buttons go full-width + stack (thumb-friendly; no dark pattern —
   Reject and Accept are both full-width so equal prominence). */
@media (max-width: 480px) {
  .cookie-banner-form { flex-direction: column; align-items: stretch; width: 100%; }
  .cookie-banner-form .btn { width: 100%; }
  .cookie-btn-reject { order: 2; }   /* Accept on top, Reject below — both full-width */
  .cookie-btn-accept { order: 1; }
}


/* ===========================================================================
   Services page (Phase G2) — plugin-driven service cards.
   The portal renders each enabled service generically from its ui_meta blob;
   these styles cover the card grid, icon slot, toggle switch, download
   buttons, inline key tables, and the native datetime-local calendar input.
   =========================================================================== */

.services-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: 20px;
  margin-top: 24px;
  /* Equal-height cards: rows stretch per-row by default, so cards in
     DIFFERENT rows end up with different heights. ``grid-auto-rows: 1fr``
     forces every row to the size of the tallest, aligning all card edges. */
  grid-auto-rows: 1fr;
}
.service-card {
  display: flex; flex-direction: column; gap: 12px;
  height: 100%;
}
.service-head { display: flex; align-items: center; gap: 12px; }
.service-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; flex-shrink: 0;
  border-radius: 10px;
  background: rgba(35, 44, 101, 0.08);
  font-size: 22px;
}
.service-title h2 {
  margin: 0; font-size: 1.05rem; font-weight: 700; line-height: 1.2;
}
.service-title .tag { margin-top: 4px; }
.service-desc { margin: 0; color: var(--ink-soft, #808080); font-size: 0.92rem; }
.service-row { display: flex; flex-direction: column; gap: 6px; }

/* Toggle switch */
.switch-label { display: inline-flex; align-items: center; gap: 10px; font-weight: 600; cursor: pointer; }
.switch { position: relative; display: inline-block; width: 40px; height: 22px; flex-shrink: 0; }
.switch input { opacity: 0; width: 0; height: 0; }
.switch .track {
  position: absolute; inset: 0; border-radius: 999px;
  background: #C9CDD6; transition: background 0.15s ease;
}
.switch .track::before {
  content: ""; position: absolute; left: 3px; top: 3px;
  width: 16px; height: 16px; border-radius: 50%;
  background: #fff; box-shadow: 0 1px 2px rgba(0,0,0,0.25);
  transition: transform 0.15s ease;
}
.switch input:checked + .track { background: var(--ist-navy, #232C65); }
.switch input:checked + .track::before { transform: translateX(18px); }
.switch input:focus-visible + .track { outline: 3px solid var(--focus, #1F4E66); outline-offset: 2px; }
.switch input:disabled + .track { opacity: 0.5; cursor: not-allowed; }

/* Inline keys table + create form */
.keys-table { margin: 8px 0; }
.keys-actions { white-space: nowrap; text-align: right; }
.inline-form { display: inline-block; margin-left: 6px; }
.key-create-form { margin-top: 10px; display: flex; flex-direction: column; gap: 8px; }
.key-create-form .form-row { display: flex; flex-direction: column; gap: 4px; }
.key-create-form label { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 11px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--ink-soft, #808080); }

/* Setup steps */
.setup-steps { margin: 8px 0 0; padding-left: 18px; display: flex; flex-direction: column; gap: 8px; font-size: 0.92rem; }
.service-setup summary, .service-keys summary { cursor: pointer; font-weight: 600; color: var(--ist-navy, #232C65); }
.service-setup[open] summary, .service-keys[open] summary { margin-bottom: 6px; }

.btn-sm { padding: 4px 10px; font-size: 0.82rem; }

@media (prefers-reduced-motion: reduce) {
  .switch .track, .switch .track::before { transition: none; }
}
