/* portal.css — the client-portal theme (web.ThemePortal).
 *
 * HAND-WRITTEN, plain CSS. Loaded by layout/base.html AFTER app.css, and
 * only when the serving process turned the theme on (cmd/billing-server,
 * clients.aegisvoip.com). It is not a Tailwind build product:
 * scripts/build-css.sh neither reads nor writes it, and it must never
 * need a utility class that is not already in app.css.
 *
 * What it does: makes the existing utility-class staff UI look like the
 * public website (aegisvoip-site/src/styles/global.css is the reference —
 * the tokens in :root below are that file's), without touching a template.
 * Three mechanisms, in this order:
 *
 *   1. Re-point Tailwind's theme variables. app.css (Tailwind v4) resolves
 *      every colour, radius and font through a custom property
 *      (--color-indigo-600, --radius-md, --font-sans…), so redefining
 *      those here re-skins every utility that uses them at once: all the
 *      indigo-* primary/link/focus utilities become the brand blues, the
 *      slate-* text and surface greys take the site's ink/muted/tint.
 *   2. Restyle by SHAPE where a variable is not enough: "an <a> or
 *      <button> with bg-indigo-600" is a primary button and becomes the
 *      site's gradient pill; "rounded-lg border bg-white" is a card.
 *   3. The portal's own chrome (portal-* classes, layout/portal.html):
 *      header, menus, footer, the login hero.
 *
 * Cascade note: app.css puts everything in @layer; these rules are
 * unlayered, so they win over any utility regardless of specificity. That
 * is why selectors here can stay short — and why a rule here must never
 * set `display` on something a script toggles with the `hidden` utility.
 *
 * Contrast: the website's --accent (#2f8cff) is a 3.3:1 colour on white
 * and is used here only for borders, rings and large fills. Text and the
 * button gradient use --accent-ink (#1c64d6, 5.3:1) and darker.
 */

@font-face {
	font-family: 'Jakarta';
	src: url('../fonts/jakarta.woff2') format('woff2');
	font-weight: 200 800;
	font-style: normal;
	font-display: swap;
}

:root {
	/* ---- website tokens (global.css :root) ---- */
	--navy-950: #020c18;
	--navy-900: #04172b;
	--navy-800: #042746; /* brand */
	--navy-700: #0b3a66;
	--navy-600: #145089;
	--ink: #0b1b2e;
	--ink-2: #33445c;
	--muted: #5b6b82;
	--line: #e2e8f0;
	--tint: #f2f6fb;
	--accent: #2f8cff;
	--accent-2: #22d3ee;
	--accent-ink: #1c64d6;
	--radius: 18px;
	--radius-sm: 12px;
	--shadow: 0 1px 2px rgba(4, 23, 43, .06), 0 8px 24px -8px rgba(4, 23, 43, .12);
	--shadow-lg: 0 2px 4px rgba(4, 23, 43, .05), 0 24px 60px -18px rgba(4, 23, 43, .28);
	--ease: cubic-bezier(.2, .7, .2, 1);
	--font: 'Jakarta', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;

	/* The website's --grad-strong (#2f8cff → #16c3e0) carries white text at
	   2–3:1. Same blue-to-cyan sweep, darkened until white text clears
	   4.5:1 along its whole length. */
	--grad-button: linear-gradient(100deg, #1c64d6 0%, #1f74dc 55%, #0b7fa8 100%);
	--grad-button-hover: linear-gradient(100deg, #1857bd 0%, #1b67c6 55%, #0a7096 100%);

	--portal-header-h: 60px;

	/* ---- 1. Tailwind theme variables, re-pointed ---- */
	--font-sans: var(--font);
	--default-font-family: var(--font);

	/* indigo-* is the app's primary/link/focus palette. Present in app.css:
	   bg-indigo-{50,100,400,500,600}, hover:bg-indigo-{50,100,500,700},
	   text-indigo-{400,600,700,800,900}, hover:text-indigo-{500,600,700},
	   border-indigo-{200,300,400,600}, border-t-indigo-600,
	   hover:border-indigo-300, focus:border-indigo-500,
	   ring-indigo-200, focus:ring-indigo-500, from-indigo-50, and the
	   50/50 + 50/60 alpha washes. 500 is the site accent, 600 the accent
	   ink (so text-indigo-600 links and bg-indigo-600 fills both pass
	   AA), 800–900 run into the brand navy. */
	--color-indigo-50: #eef6ff;
	--color-indigo-100: #dcebff;
	--color-indigo-200: #bcd9ff;
	--color-indigo-300: #8fc0ff;
	--color-indigo-400: #5aa4ff;
	--color-indigo-500: #2f8cff;
	--color-indigo-600: #1c64d6;
	--color-indigo-700: #1653b4;
	--color-indigo-800: #0b3a66;
	--color-indigo-900: #042746;

	/* slate-*: page tint, hairlines, and the site's ink/muted text. 300
	   and 400 are left alone (control borders, de-emphasised text). */
	--color-slate-50: #f2f6fb;
	--color-slate-100: #e9eff7;
	--color-slate-200: #dde5ef;
	--color-slate-500: #5b6b82;
	--color-slate-600: #46566d;
	--color-slate-700: #33445c;
	--color-slate-800: #17283d;
	--color-slate-900: #0b1b2e;

	/* Radii: the site's 12px/18px cards, scaled for a dense UI. */
	--radius-md: .625rem;
	--radius-lg: .75rem;
	--radius-xl: 1rem;
	--radius-2xl: 1.125rem;

	color-scheme: light;
}

/* ------------------------------------------------------------------ base */

html { scroll-padding-top: calc(var(--portal-header-h) + 12px); }
body {
	font-family: var(--font);
	color: var(--ink);
	background: var(--tint);
	-webkit-font-smoothing: antialiased;
	text-rendering: optimizeLegibility;
}
h1, h2, h3 { letter-spacing: -0.02em; }
h1 { font-weight: 750; }
::selection { background: rgba(47, 140, 255, .25); }

/* One visible keyboard focus everywhere, the website's. Form controls get
   a ring instead (below) so a focused field does not grow a second box. */
:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; border-radius: 6px; }
.portal-header :focus-visible, .portal-login-intro :focus-visible { outline-color: #7dd3fc; }
.portal-menu :focus-visible { outline-color: var(--accent-ink); }

input[type='checkbox'], input[type='radio'] { accent-color: var(--accent-ink); }

/* ------------------------------------------------------------------ buttons
   Primary: any link/button filled with bg-indigo-600 — the site's .btn. */
:is(a, button, summary, label, input[type='submit'], input[type='button']).bg-indigo-600 {
	background-image: var(--grad-button);
	background-color: var(--accent-ink);
	border-radius: 999px;
	font-weight: 700;
	letter-spacing: -0.005em;
	box-shadow: 0 6px 16px -8px rgba(28, 100, 214, .75), inset 0 1px 0 rgba(255, 255, 255, .22);
	transition: transform .2s var(--ease), box-shadow .2s var(--ease);
}
:is(a, button, summary, label, input[type='submit'], input[type='button']).bg-indigo-600:hover {
	background-image: var(--grad-button-hover);
	box-shadow: 0 10px 20px -10px rgba(28, 100, 214, .9), inset 0 1px 0 rgba(255, 255, 255, .22);
	transform: translateY(-1px);
}
:is(a, button, input).bg-indigo-600:is(:disabled, [aria-disabled='true']) { transform: none; box-shadow: none; }

/* Secondary and tinted buttons (white/bordered, indigo-50, amber…): the
   same pill, so every action on a page has one silhouette; their own
   colours are untouched. Destructive actions keep the app's reds — a
   solid red pill (bg-red-600) or red text — and are never given the brand
   gradient, so "delete" cannot be mistaken for "save". */
:is(a, button, summary, input[type='submit'], input[type='button']).rounded-md { border-radius: 999px; }
:is(a, button).rounded-md.border.bg-white {
	border-color: #cfd9e6;
	font-weight: 600;
	transition: border-color .15s, background-color .15s, color .15s;
}
:is(a, button).rounded-md.border.bg-white:hover { border-color: var(--accent); }
:is(a, button).bg-red-600 { font-weight: 700; box-shadow: 0 6px 16px -8px rgba(220, 38, 38, .7); }

/* A module's own section tabs (Billing's bar): the active tab is solid
   slate-900 in the stock UI — brand navy here. */
a.bg-slate-900 { background-color: var(--navy-800); }
a.bg-slate-900:hover { background-color: var(--navy-700); }

/* ------------------------------------------------------------------ forms */
:is(input:not([type='checkbox'], [type='radio'], [type='submit'], [type='button'], [type='file'], [type='range'], [type='color']), select, textarea) {
	font-family: inherit;
}
:is(input:not([type='checkbox'], [type='radio'], [type='submit'], [type='button'], [type='file'], [type='range'], [type='color']), select, textarea).border {
	border-color: #cfd9e6;
	background-color: #fff;
	transition: border-color .15s, box-shadow .15s;
}
:is(input:not([type='checkbox'], [type='radio'], [type='submit'], [type='button'], [type='file'], [type='range'], [type='color']), select, textarea):focus,
:is(input:not([type='checkbox'], [type='radio'], [type='submit'], [type='button'], [type='file'], [type='range'], [type='color']), select, textarea):focus-visible {
	outline: none;
	border-color: var(--accent);
	box-shadow: 0 0 0 3px rgba(47, 140, 255, .28);
}
::placeholder { color: #8493a8; opacity: 1; }
label { color: var(--ink-2); }

/* ------------------------------------------------------------------ cards
   "rounded-lg|xl border bg-white" is a card everywhere in the app. */
:is(.rounded-lg, .rounded-xl).border.bg-white { border-color: rgba(4, 23, 43, .08); }
:is(div, section, form, article, table, dl, ul, ol, details, nav).shadow-sm { --tw-shadow: var(--shadow); }
:is(div, section, form, article).shadow-lg, :is(div, section, form, article).shadow-xl { --tw-shadow: var(--shadow-lg); }

/* ------------------------------------------------------------------ tables */
thead.bg-slate-50, thead tr.bg-slate-50 { background-color: #edf2f8; }
thead th { color: var(--ink-2); font-weight: 650; }
tbody tr.row-link { cursor: pointer; transition: background-color .12s; }
tbody tr.row-link:hover { background-color: #f5f9ff; }

/* ------------------------------------------------------------------ badges */
span.rounded-full { font-weight: 600; }

/* ------------------------------------------------------------------ tabs
   Underline tab strips (Configuration): heavier active tab; the colours
   already follow the indigo variables. */
nav > a.border-b-2 { font-weight: 600; }

/* Breadcrumb bar sits directly under the navy header. */
nav[aria-label='Breadcrumb'] { background: #fff; border-color: rgba(4, 23, 43, .08); }

/* ------------------------------------------------------------------ header */
.portal-header {
	position: fixed; inset: 0 0 auto; z-index: 40;
	height: var(--portal-header-h);
	color: #fff;
	background: linear-gradient(90deg, var(--navy-900), var(--navy-800));
	box-shadow: 0 1px 0 rgba(255, 255, 255, .06), 0 6px 20px -12px rgba(2, 12, 24, .6);
	--logo-cut: var(--navy-900);
}
.portal-header-spacer { height: var(--portal-header-h); }
.portal-header-inner {
	height: 100%;
	max-width: 80rem; margin-inline: auto;
	padding-inline: clamp(12px, 3vw, 32px);
	display: flex; align-items: center; gap: clamp(8px, 2vw, 24px);
}
.portal-brand { display: inline-flex; align-items: center; gap: 10px; flex: none; color: #fff; text-decoration: none; border-radius: 10px; }
.portal-mark { height: 36px; width: auto; flex: none; display: block; }
.portal-wordmark { display: inline-flex; flex-direction: column; line-height: 1; }
.portal-word { font-size: 1.32rem; font-weight: 800; letter-spacing: .07em; }
.portal-caption { margin-top: 4px; font-size: .53rem; font-weight: 700; letter-spacing: .3em; text-transform: uppercase; opacity: .8; white-space: nowrap; }

.portal-nav-link {
	display: inline-flex; align-items: center; gap: 8px;
	padding: 7px 12px; border-radius: 10px;
	color: rgba(255, 255, 255, .86); text-decoration: none;
	font-weight: 600; font-size: .9rem; white-space: nowrap;
	cursor: pointer; list-style: none;
	transition: color .2s, background-color .2s;
}
.portal-nav-link::-webkit-details-marker { display: none; }
.portal-nav-link::marker { content: ''; }
.portal-nav-link:hover, details[open] > .portal-nav-link, .portal-nav-link[aria-current='page'] { color: #fff; background: rgba(255, 255, 255, .1); }
/* A chevron on the disclosure buttons (System, More), as on the website. */
details > summary.portal-nav-link:not(.portal-user)::after {
	content: ''; width: 7px; height: 7px; margin-top: -3px;
	border-right: 2px solid currentColor; border-bottom: 2px solid currentColor;
	transform: rotate(45deg); opacity: .7; transition: transform .2s var(--ease), margin .2s;
}
details[open] > summary.portal-nav-link:not(.portal-user)::after { transform: rotate(225deg); margin-top: 3px; }

.portal-siblings { display: none; align-items: center; gap: 4px; padding-left: 16px; border-left: 1px solid rgba(255, 255, 255, .14); }
@media (min-width: 1024px) { .portal-siblings { display: flex; } }

.portal-user { padding: 5px 10px 5px 5px; }
.portal-avatar {
	display: inline-flex; align-items: center; justify-content: center;
	width: 30px; height: 30px; border-radius: 50%; flex: none;
	background: rgba(255, 255, 255, .14); box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .22);
	font-size: .78rem; font-weight: 700; color: #fff;
}
.portal-user-email { display: none; max-width: 16rem; overflow: hidden; text-overflow: ellipsis; }
@media (min-width: 900px) { .portal-user-email { display: inline; } }

.portal-menu {
	position: absolute; right: 0; top: calc(100% + 8px); z-index: 50;
	min-width: 13.5rem; padding: 6px;
	background: #fff; color: var(--ink);
	border-radius: 14px;
	box-shadow: var(--shadow-lg), 0 0 0 1px rgba(4, 23, 43, .06);
}
.portal-menu-left { right: auto; left: 0; }
.portal-menu a, .portal-menu button {
	display: block; width: 100%; text-align: left;
	padding: 8px 12px; border-radius: 9px;
	font: inherit; font-size: .9rem; font-weight: 600; color: var(--ink);
	background: none; border: 0; cursor: pointer; text-decoration: none;
	transition: background-color .15s;
}
.portal-menu a:hover, .portal-menu button:hover, .portal-menu a:focus-visible, .portal-menu button:focus-visible { background: var(--tint); }
.portal-menu form { margin-top: 4px; padding-top: 4px; border-top: 1px solid var(--line); }

.portal-login-link {
	display: inline-flex; align-items: center; flex: none;
	padding: 8px 18px; border-radius: 999px;
	color: #fff; font-weight: 700; font-size: .9rem; text-decoration: none;
	background-image: var(--grad-button);
	box-shadow: 0 8px 20px -10px rgba(47, 140, 255, .8), inset 0 1px 0 rgba(255, 255, 255, .22);
}
.portal-login-link:hover { background-image: var(--grad-button-hover); }

/* A phone keeps the header to one row: the nav collapses into "More"
   (base.html's priority-plus script), the caption under the wordmark and
   the email beside the avatar go, and the gaps tighten. */
@media (max-width: 480px) {
	.portal-caption { display: none; }
	.portal-word { font-size: 1.15rem; }
	.portal-mark { height: 32px; }
	.portal-nav-link { padding: 7px 9px; }
	.portal-menu { max-width: calc(100vw - 24px); }
}

/* ------------------------------------------------------------------ footer */
.portal-footer {
	max-width: 80rem; margin: 8px auto 0;
	padding: 0 clamp(16px, 3vw, 32px) 24px;
	color: var(--muted); font-size: .8rem;
}
.portal-footer-stats { padding-bottom: 10px; font-family: var(--font-mono); font-size: .75rem; color: #8493a8; }
.portal-footer-brand {
	display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 6px 16px;
	padding-top: 14px; border-top: 1px solid rgba(4, 23, 43, .1);
}
.portal-footer-brand a { color: var(--accent-ink); font-weight: 600; text-decoration: none; }
.portal-footer-brand a:hover { text-decoration: underline; }

/* ------------------------------------------------------------------ login
   The sign-in page opens the way the website does: a navy hero with the
   logo, and the form as a white card on it. :has() scopes the dark
   backdrop to this one page; a browser without it gets the same card on
   the ordinary tinted page, which is still a complete sign-in page. */
body:has(.portal-login) {
	background:
		radial-gradient(1200px 600px at 80% -10%, rgba(47, 140, 255, .28), transparent 60%),
		radial-gradient(900px 500px at -10% 110%, rgba(34, 211, 238, .16), transparent 60%),
		linear-gradient(180deg, var(--navy-900), var(--navy-800) 70%, #06345c);
	background-attachment: fixed;
	min-height: 100%;
}
html:has(.portal-login) { background: var(--navy-900); }
body:has(.portal-login) .portal-header { background: transparent; box-shadow: none; }
body:has(.portal-login) .portal-header .portal-brand,
body:has(.portal-login) .portal-login-link { visibility: hidden; }
body:has(.portal-login) .portal-footer { color: rgba(226, 238, 255, .6); }
body:has(.portal-login) .portal-footer-brand { border-top-color: rgba(255, 255, 255, .12); }
body:has(.portal-login) .portal-footer-brand a { color: #7cc0ff; }

.portal-login {
	display: grid; gap: clamp(24px, 5vw, 64px); align-items: center;
	min-height: calc(100vh - var(--portal-header-h) - 150px);
	padding-block: clamp(8px, 4vh, 48px);
}
@media (min-width: 900px) { .portal-login { grid-template-columns: minmax(0, 1.1fr) minmax(0, 24rem); } }
.portal-login-intro { color: #fff; --logo-cut: var(--navy-900); }
.portal-login-logo { display: flex; align-items: center; gap: 14px; }
.portal-login-logo .portal-mark { height: 64px; }
.portal-login-logo .portal-word { font-size: 2.3rem; }
.portal-login-logo .portal-caption { display: block; margin-top: 7px; font-size: .78rem; }
.portal-eyebrow {
	display: inline-flex; margin-top: 28px;
	padding: 6px 14px; border-radius: 999px;
	font-size: .72rem; font-weight: 700; letter-spacing: .14em; text-transform: uppercase;
	color: #bfe3ff; background: rgba(255, 255, 255, .06); box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .14);
}
.portal-login-title {
	margin-top: 18px; max-width: 18ch;
	font-size: clamp(1.9rem, 1.4rem + 2.2vw, 3rem); line-height: 1.06; letter-spacing: -0.035em; font-weight: 780;
	text-wrap: balance;
}
.portal-login-sub { margin-top: 14px; max-width: 44ch; font-size: 1.02rem; color: rgba(226, 238, 255, .78); }
/* The stock form wrapper is "mx-auto mt-12 max-w-sm"; in the hero it is a
   grid cell and the card takes the site's radius and deep shadow. */
.portal-login > .max-w-sm { margin-top: 0; width: 100%; }
.portal-login > .max-w-sm > .bg-white {
	border: 0; border-radius: var(--radius);
	padding: 28px;
	box-shadow: var(--shadow-lg);
}
.portal-login button[type='submit'] { padding-block: .7rem; font-size: .95rem; }

@media (prefers-reduced-motion: reduce) {
	* { transition: none !important; }
}
