/* NetFoundry MCP Connect. Design tokens from ezziti's style.css. */

:root {
    /* Both schemes are declared here, and light-dark() picks one from the
       color-scheme below. That keeps a single list of tokens: the previous
       shape duplicated every dark value in a media query, which is where a
       three-way switch would have had to duplicate it a second time. It
       also makes form controls and scrollbars follow the theme. */
    color-scheme: light dark;

    --brand-primary: #0066FF;
    --brand-primary-hover: #0052cc;
    --brand-secondary: #00489f;
    --brand-secondary-hover: #003d82;
    --color-danger: #dc2626;
    --color-danger-hover: #b91c1c;
    --color-success: #16a34a;
    --color-warning: #d97706;
    --text-primary: light-dark(#111827, #e5e7eb);
    --text-secondary: light-dark(#374151, #d1d5db);
    --text-tertiary: light-dark(#6b7280, #9ca3af);
    --text-muted: light-dark(#9ca3af, #6b7280);
    --bg-page: light-dark(#f9fafb, #0a0a0a);
    --bg-white: light-dark(#ffffff, #141414);
    --bg-subtle: light-dark(#f3f4f6, #1e1e1e);
    --bg-divider: light-dark(#e5e7eb, #2a2a2a);
    --border-card: light-dark(#d1d5db, #2a2a2a);
    --border-divider: light-dark(#e5e7eb, #222222);
    --border-dark: light-dark(#9ca3af, #444444);
    --radius: 5px;
    --radius-lg: 7px;
    --radius-pill: 9999px;
    --shadow-card: light-dark(0 1px 3px rgba(0,0,0,0.06), 0 1px 3px rgba(0,0,0,0.3));
    --shadow-nav: light-dark(0 1px 2px rgba(0,0,0,0.04), 0 1px 2px rgba(0,0,0,0.2));
    --height-nav: 56px;
}

/* The person's choice, when they have made one. Without the attribute the
   browser follows the operating system, which is the default and the case
   that needs no control at all. The attribute is rendered server-side from
   a cookie, so the first paint is already correct and the page never
   flashes the wrong theme. */
:root[data-theme="light"] { color-scheme: light; }
:root[data-theme="dark"] { color-scheme: dark; }

* { box-sizing: border-box; }
html { font-family: 'Inter', system-ui, -apple-system, sans-serif; font-size: 15px; }
body { margin: 0; background: var(--bg-page); color: var(--text-primary); line-height: 1.5; }
a { color: var(--brand-primary); text-decoration: none; }
a:hover { text-decoration: underline; }
code, pre { font-family: 'SF Mono', SFMono-Regular, ui-monospace, Menlo, Consolas, monospace; font-size: 0.9em; }
pre { background: var(--bg-subtle); border: 1px solid var(--border-divider); border-radius: var(--radius); padding: 0.75rem 1rem; overflow-x: auto; }

/* Layout */
.topbar { height: var(--height-nav); background: var(--bg-white); border-bottom: 1px solid var(--border-divider); box-shadow: var(--shadow-nav);
          display: flex; align-items: center; padding: 0 1.25rem; gap: 1rem; }
.topbar .brand { display: flex; align-items: center; gap: 0.6rem; font-weight: 600; color: var(--text-primary); text-decoration: none; }
.topbar .brand:hover { text-decoration: none; }

/* The logo ships in two colourways because the console has two themes: the
   wordmark is navy on light and white on dark. Both are the same artwork at
   the same aspect ratio, so swapping one for the other never moves the
   layout. Only one is ever displayed, so the hidden one's alt text is not
   read out twice. */
.nf-logo { display: block; width: auto; }
.nf-logo-reverse { display: none; }
/* The wordmark occupies the upper two thirds of the artwork and the
   tagline the lower one, so centring the image leaves the wordmark sitting
   high against the product name beside it. Nudging down by that offset
   lines the two pieces of text up, which is what the eye compares. */
.topbar .nf-logo { height: 30px; position: relative; top: 2px; }
/* The card below carries the 5rem top margin, so the logo takes that
   spacing instead and sits with the card rather than adrift above it. */
.logo-centered { display: flex; justify-content: center; margin: 5rem auto 1.25rem; }
.logo-centered + .login-box { margin-top: 0; }
.logo-centered .nf-logo { height: 46px; }
@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) .nf-logo-light { display: none; }
    :root:not([data-theme="light"]) .nf-logo-reverse { display: block; }
}
:root[data-theme="dark"] .nf-logo-light { display: none; }
:root[data-theme="dark"] .nf-logo-reverse { display: block; }
:root[data-theme="light"] .nf-logo-light { display: block; }
:root[data-theme="light"] .nf-logo-reverse { display: none; }
.topbar .tenant { color: var(--text-tertiary); }
.topbar .spacer { flex: 1; }
.topbar .who { color: var(--text-secondary); font-size: 0.9rem; }
.shell { display: flex; min-height: calc(100vh - var(--height-nav)); }
.sidenav { width: 220px; padding: 1rem 0; border-right: 1px solid var(--border-divider); background: var(--bg-white); flex-shrink: 0; }
.sidenav a { display: block; padding: 0.5rem 1.25rem; color: var(--text-secondary); }
.sidenav a:hover { background: var(--bg-subtle); text-decoration: none; }
.sidenav a.active { background: #e0ecff; color: var(--brand-secondary); font-weight: 500; }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .sidenav a.active { background: #1a2a44; color: #93c5fd; } }
:root[data-theme="dark"] .sidenav a.active { background: #1a2a44; color: #93c5fd; }

/* Theme control in the topbar. The global select rule sets width:100%,
   which in the topbar's flex row makes it span whatever is left over. */
.theme-pick { width: auto; font: inherit; font-size: 0.85rem; padding: 0.2rem 1.4rem 0.2rem 0.5rem;
    border-radius: var(--radius); border: 1px solid var(--border-divider);
    background: var(--bg-white); color: var(--text-secondary); }
main { flex: 1; padding: 1.5rem 2rem; max-width: 1100px; }
/* The signed-out pages (sign in, consent, the user's own page, errors)
   have no sidenav, so their main is centred in the window. The console's
   main is a flex item beside the sidenav and starts against it: giving
   both `margin: 0 auto` would push every console page 40px off the nav. */
body > main { margin: 0 auto; }
@media (max-width: 720px) { .shell { flex-direction: column; } .sidenav { width: auto; display: flex; flex-wrap: wrap; border-right: 0; border-bottom: 1px solid var(--border-divider); } main { padding: 1rem; } }

h1 { font-size: 1.5rem; margin: 0 0 1rem; }
h2 { font-size: 1.1rem; margin: 1.5rem 0 0.75rem; }
.muted { color: var(--text-tertiary); }
.small { font-size: 0.85rem; }

/* Cards and tables */
.card { background: var(--bg-white); border: 1px solid var(--border-card); border-radius: var(--radius-lg); box-shadow: var(--shadow-card); padding: 1rem 1.25rem; margin-bottom: 1rem; }
/* A card's leading heading sits against the card's own padding rather
   than adding to it. This was an inline style on fifteen separate <h2>. */
.card h2:first-child { margin-top: 0; }
.stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 1rem; margin-bottom: 1rem; }
.stat { background: var(--bg-white); border: 1px solid var(--border-card); border-radius: var(--radius-lg); padding: 1rem; }
.stat .n { font-size: 1.8rem; font-weight: 600; }
.stat .l { color: var(--text-tertiary); font-size: 0.85rem; }
table { width: 100%; border-collapse: collapse; }
th, td { text-align: left; padding: 0.5rem 0.6rem; border-bottom: 1px solid var(--border-divider); vertical-align: top; }
th { color: var(--text-tertiary); font-weight: 500; font-size: 0.85rem; }
/* The dividers are between rows, so the last row has none. Both cell
   kinds, because a table whose rows are labelled (th scope=row) would
   otherwise keep a line under the label column alone. Scoped to tbody so
   that a column header row, which is the last row of its own thead, keeps
   the line that separates it from the data. */
tbody tr:last-child td, tbody tr:last-child th { border-bottom: 0; }

/* Forms */
form.stack > * { display: block; margin-bottom: 0.9rem; }
label { display: block; font-size: 0.85rem; color: var(--text-secondary); margin-bottom: 0.25rem; }
input[type=text], input[type=url], input[type=password], input[type=number], select, textarea {
    width: 100%; max-width: 520px; padding: 0.5rem 0.65rem; font: inherit; color: var(--text-primary);
    background: var(--bg-white); border: 1px solid var(--border-card); border-radius: var(--radius); }
input:focus, select:focus, textarea:focus { outline: 2px solid var(--brand-primary); outline-offset: 0; border-color: var(--brand-primary); }
.hint { color: var(--text-tertiary); font-size: 0.8rem; margin-top: 0.2rem; }
.btn { display: inline-block; padding: 0.5rem 0.9rem; font: inherit; font-weight: 500; border-radius: var(--radius); border: 1px solid var(--border-card);
       background: var(--bg-white); color: var(--text-primary); cursor: pointer; }
.btn:hover { background: var(--bg-subtle); text-decoration: none; }
.btn.primary { background: var(--brand-primary); border-color: var(--brand-primary); color: #fff; }
.btn.primary:hover { background: var(--brand-primary-hover); }
.btn.danger { color: var(--color-danger); border-color: var(--color-danger); }
.btn.danger:hover { background: var(--color-danger); color: #fff; }
.btn.small { padding: 0.25rem 0.6rem; font-size: 0.85rem; }
.actions { display: flex; gap: 0.5rem; align-items: center; flex-wrap: wrap; }

/* Status */
.pill { display: inline-block; padding: 0.1rem 0.55rem; border-radius: var(--radius-pill); font-size: 0.75rem; font-weight: 600; }
.pill.ok { background: #dcfce7; color: #166534; }
.pill.bad { background: #fee2e2; color: #991b1b; }
.pill.warn { background: #ffedd5; color: #9a3412; }
.pill.off { background: var(--bg-subtle); color: var(--text-tertiary); }
.flash { padding: 0.6rem 0.9rem; border-radius: var(--radius); margin-bottom: 1rem; font-size: 0.95rem; }
.flash.ok { background: #dcfce7; color: #166534; }
.flash.err { background: #fee2e2; color: #991b1b; }
/* A repair plan: the verb leads each line, and a removal is the one the
   reader has to weigh, so it is the only one that is coloured. */
.plan li::marker { color: var(--text-tertiary); }
.plan li.destructive { color: var(--color-danger); font-weight: 500; }
/* The same list nested in a table cell, where it follows the state pill. */
.plan-nested { margin: 0.25rem 0 0; }
.grid-check { text-align: center; }
.num { text-align: right; font-variant-numeric: tabular-nums; }
h3 { font-size: 0.95rem; margin: 1rem 0 0.5rem; }

/* Tabs */
.tabs { display: flex; gap: 0.25rem; border-bottom: 1px solid var(--border-divider); margin: 0.75rem 0; }
.tab { font: inherit; font-weight: 500; padding: 0.4rem 0.8rem; background: none; border: 0; border-bottom: 2px solid transparent; color: var(--text-tertiary); cursor: pointer; margin-bottom: -1px; }
.tab.active { color: var(--brand-secondary); border-bottom-color: var(--brand-primary); }
.tab:hover { color: var(--text-primary); }
.login-box { max-width: 26rem; margin: 5rem auto; }
.error-box { border-left: 4px solid var(--color-danger); }
.error-box h1 { margin-top: 0.25rem; }

/* Help drawer, the ezziti pattern: a ? beside a heading opens a topic in a
   right-hand drawer. */
.help-icon { display: inline-flex; align-items: center; justify-content: center; width: 18px; height: 18px; border-radius: 50%;
             border: 1px solid var(--border-card); background: var(--bg-subtle); color: var(--text-tertiary); font: 600 0.7rem/1 inherit;
             font-family: inherit; cursor: pointer; vertical-align: middle; margin-left: 6px; padding: 0; }
.help-icon:hover { border-color: var(--brand-primary); color: var(--brand-primary); }
.help-drawer { position: fixed; top: 0; right: 0; width: 380px; max-width: 90vw; height: 100vh; background: var(--bg-white);
               border-left: 1px solid var(--border-card); box-shadow: -4px 0 24px rgba(0,0,0,0.1); transform: translateX(100%);
               transition: transform 0.25s ease; z-index: 1100; display: flex; flex-direction: column; }
.help-drawer-open { transform: translateX(0); }
.help-drawer-header { display: flex; align-items: center; justify-content: space-between; padding: 1rem 1.25rem; border-bottom: 1px solid var(--border-card); }
.help-drawer-header h3 { margin: 0; font-size: 1rem; }
.help-drawer-close { background: none; border: 0; font-size: 1.4rem; cursor: pointer; color: var(--text-tertiary); padding: 0 4px; line-height: 1; }
.help-drawer-close:hover { color: var(--text-primary); }
.help-drawer-body { padding: 1.25rem; overflow-y: auto; flex: 1; font-size: 0.9rem; line-height: 1.6; color: var(--text-secondary); }
.help-drawer-body p { margin: 0 0 0.75rem; }
.help-drawer-body ul { margin: 0 0 0.75rem; padding-left: 1.25rem; }
.help-drawer-body li { margin-bottom: 0.4rem; }
.help-drawer-overlay { display: none; position: fixed; inset: 0; z-index: 1099; }
.help-drawer-overlay-open { display: block; }

/* ---- Keyboard focus -------------------------------------------------
   Only form fields had a focus style, so tabbing through the console was
   invisible. :focus-visible keeps it off mouse clicks. */
:focus-visible { outline: 2px solid var(--brand-primary); outline-offset: 2px; border-radius: 2px; }

.skip-link { position: absolute; left: -9999px; top: 0; z-index: 100; padding: 0.5rem 0.9rem;
    background: var(--bg-white); border: 1px solid var(--border-card); border-radius: var(--radius); }
.skip-link:focus { left: 0.5rem; top: 0.5rem; }

/* Visible to a screen reader, not on screen. For the word behind a dot. */
.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; }

/* ---- Page header ----------------------------------------------------
   Title and description on the left, the page's primary action on the
   right, so the action is visible without scrolling past the data. */
.page-head { display: flex; align-items: flex-start; gap: 1rem; margin-bottom: 1rem; }
.page-head-text { flex: 1; min-width: 0; }
.page-head-text h1 { margin-bottom: 0.25rem; }
.page-head-text p { margin: 0; }
.page-head-actions { flex-shrink: 0; display: flex; gap: 0.5rem; align-items: center; }
@media (max-width: 720px) { .page-head { flex-direction: column; } }

/* ---- Status dot -----------------------------------------------------
   A glyph in a fixed leading column scans faster down a table than a
   pill of varying width in the middle of a row. */
.dot-col { width: 1.5rem; padding-right: 0; }
.dot { display: inline-block; width: 0.6rem; height: 0.6rem; border-radius: 50%; background: var(--text-muted); }
.dot.ok { background: #16a34a; }
.dot.bad { background: #dc2626; }
.dot.warn { background: #ca8a04; }
.dot.off { background: var(--border-dark); }

/* ---- Row actions ----------------------------------------------------
   One menu per row instead of every action always on screen. Built from
   <details> so it works without JavaScript. */
.row-menu { position: relative; display: inline-block; }
.row-menu > summary { list-style: none; cursor: pointer; padding: 0.1rem 0.5rem; border-radius: var(--radius);
    color: var(--text-secondary); font-weight: 600; user-select: none; }
.row-menu > summary::-webkit-details-marker { display: none; }
.row-menu > summary:hover, .row-menu[open] > summary { background: var(--bg-subtle); }
.row-menu-items { position: absolute; right: 0; top: 100%; z-index: 20; min-width: 12rem; padding: 0.25rem;
    background: var(--bg-white); border: 1px solid var(--border-card); border-radius: var(--radius-lg);
    box-shadow: var(--shadow-card); }
.row-menu-items form { margin: 0; }
.row-menu-items button, .row-menu-items a { display: block; width: 100%; text-align: left; border: 0;
    background: none; padding: 0.4rem 0.6rem; border-radius: var(--radius); font: inherit; color: var(--text-primary);
    cursor: pointer; white-space: nowrap; }
.row-menu-items button:hover, .row-menu-items a:hover { background: var(--bg-subtle); text-decoration: none; }
.row-menu-items button.danger { color: #b91c1c; }

/* ---- Copy to clipboard ---------------------------------------------- */
.copy { border: 1px solid var(--border-divider); background: var(--bg-white); border-radius: var(--radius);
    padding: 3px 7px; margin-left: 0.4rem; cursor: pointer; color: var(--text-secondary); line-height: 1;
    vertical-align: middle; font: inherit; font-size: 0.85rem; }
.copy:hover { background: var(--bg-subtle); color: var(--text-primary); }
.copy svg { display: block; }

/* Audit: one date heading per day rather than the date on every row. */
.day-row th { background: var(--bg-subtle); color: var(--text-secondary); font-size: 0.8rem;
    font-weight: 600; text-align: left; padding: 0.35rem 0.6rem; }
details.raw { margin-top: 0.25rem; }
details.raw > summary { cursor: pointer; }
details.raw code { display: block; margin-top: 0.25rem; white-space: pre-wrap; word-break: break-all; }

/* A table cell must stay a table cell: .actions sets display:flex, which
   overrides display:table-cell and drops the cell out of the row, so its
   border lands at a different height from its neighbours. Cells that hold
   controls use this instead and put the flex on an inner element. */
td.cell-actions { white-space: nowrap; text-align: right; vertical-align: top; }
td.cell-actions > .actions { justify-content: flex-end; }

/* Rendered markdown. The guides are written for reading, so the column is
   held to a readable measure rather than stretched to the card. */
.doc { max-width: 46rem; }
.doc h1 { margin-top: 0; }
.doc h2 { margin-top: 1.75rem; padding-top: 0.75rem; border-top: 1px solid var(--border-divider); }
.doc h3 { margin-top: 1.25rem; }
.doc code { background: var(--bg-subtle); padding: 0.1rem 0.3rem; border-radius: 3px; }
.doc pre code { background: none; padding: 0; }
.doc table { margin: 1rem 0; }
.doc td, .doc th { vertical-align: top; }
.doc blockquote { margin: 1rem 0; padding: 0.5rem 1rem; border-left: 3px solid var(--border-card);
    color: var(--text-secondary); background: var(--bg-subtle); border-radius: 0 var(--radius) var(--radius) 0; }
.doc li { margin: 0.25rem 0; }
/* The guides are reference rather than a place you work, so they sit apart
   from the pages the console is made of. */
.sidenav .nav-docs { margin-top: auto; border-top: 1px solid var(--border-divider); color: var(--text-tertiary); }

/* Spacing and width utilities
 *
 * Each of these reproduces exactly one inline style that used to sit in a
 * template. They are here rather than there because the content security
 * policy refuses a style attribute: see internal/httpguard. Values are
 * unchanged, so the rendering is the same as before the move.
 *
 * They are named after what they do rather than where they are used,
 * because the same spacing turns up in unrelated places and a semantic
 * name would be wrong in half of them.
 */
.flush-top { margin-top: 0; }
.gap-top-sm { margin-top: 0.5rem; }
.gap-top { margin-top: 0.75rem; }
.tight-bottom { margin-bottom: 0.4rem; }
.tight-bottom-sm { margin-bottom: 0.3rem; }
.hint-flush { margin: 0 0 0.2rem; }
.nowrap { white-space: nowrap; }
.scroll-x { overflow-x: auto; }
.inline-label { display: inline-block; margin-right: 1rem; }

/* The getting-started list on the overview. */
.steps { margin: 0; padding-left: 1.25rem; }
.steps li { margin: 0.3rem 0; }

/* Field widths in rem, sized to their content: a port is 8, a slug or an
   audit filter 12, a hostname or tenant id 16, a backend address 20, a
   display name or group 24. Named by size rather than purpose because the
   same width serves unrelated fields, and a mechanical name is one a
   reader can check against the markup.
 *
 * Each is written out for the form controls as well as bare, because the
 * base rule above is `input[type=text], ... { max-width: 520px }`, which
 * carries a type and an attribute against this class's one class and so
 * wins on specificity. The compound selectors match it and come later, so
 * they win on order. This is the one thing a style attribute did for free
 * and a class does not: it is also why these widths have to be checked in
 * a browser rather than reasoned about. */
.w-8, input.w-8, select.w-8, textarea.w-8 { max-width: 8rem; }
.w-12, input.w-12, select.w-12, textarea.w-12 { max-width: 12rem; }
.w-16, input.w-16, select.w-16, textarea.w-16 { max-width: 16rem; }
.w-20, input.w-20, select.w-20, textarea.w-20 { max-width: 20rem; }
.w-24, input.w-24, select.w-24, textarea.w-24 { max-width: 24rem; }
