/* PawDNS UI. Plain CSS, no build step.
 *
 * Colours: ONLY var(--token)s. The tokens (light + dark, PawHost TenantOS scheme) come from
 * config('pawdns.branding.theme') and are inlined per page by resources/views/partials/theme-head
 * (App\Support\Theme\ThemeTokens), so a tenant can override them (white-label, DESIGN.md §7.3).
 * Do not add hex/rgb colours here. Use --<c>-text (AA-safe) for text, --<c> for fills/borders,
 * --on-<c> for text on a --<c> fill. Top bar, theme switcher and user menu: pawdns-chrome.css.
 */
* { box-sizing: border-box; }
html { background: var(--background); }
body { margin: 0; min-height: 100vh; background: var(--background); color: var(--text); line-height: 1.45;
       font-family: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif; }
a { color: var(--primary-text); text-decoration: none; } a:hover { text-decoration: underline; }
h1 { font-size: 1.5rem; letter-spacing: -.01em; margin: 0 0 1rem; color: var(--text); }
h2 { font-size: 1.1rem; margin: 1.5rem 0 .75rem; } h3 { font-size: 1rem; }
code, .mono { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: .9em; }
pre { background: var(--info-box); color: var(--text); border-radius: .35rem; padding: .5rem .7rem; overflow-x: auto; }
.muted { color: var(--text-muted); } .small { font-size: .85rem; }
:focus-visible { outline: 2px solid var(--primary-text); outline-offset: 2px; }
::selection { background: var(--primary); color: var(--on-primary); }

/* ---- app shell: sidebar + content ---- */
.shell { display: flex; min-height: calc(100vh - var(--topbar-h)); }
.sidebar { flex: 0 0 var(--sidebar-w); width: var(--sidebar-w); background: var(--sidebar); color: var(--sidebar-text);
           position: sticky; top: var(--topbar-h); height: calc(100vh - var(--topbar-h)); overflow-y: auto; padding: .75rem 0 1.5rem; }
.sidebar ul { list-style: none; margin: 0; padding: 0; }
.sidebar a.nav-link { display: flex; align-items: center; gap: .75rem; padding: .48rem 1.1rem; color: var(--sidebar-text); font-size: .92rem;
                      border-left: 3px solid transparent; }
.sidebar a.nav-link svg { flex: none; color: var(--sidebar-icon); }
/* Safety net: icon size never depends on the width/height attributes (see partials/nav-icon). */
.sidebar .icon { width: 18px; height: 18px; flex: none; }
.sidebar summary .icon.chevron { width: 16px; height: 16px; }
.sidebar a.nav-link:hover { background: var(--sidebar-hover); text-decoration: none; }
.sidebar a.nav-link.active { background: var(--sidebar-selected); color: var(--sidebar-text-active); font-weight: 600; border-left-color: var(--sidebar-icon-active); }
.sidebar a.nav-link.active svg { color: var(--sidebar-icon-active); }
.sidebar .nav-badge { margin-left: auto; min-width: 1.6rem; padding: 0 .45rem; border-radius: 1rem; font-size: .75rem; font-weight: 600; line-height: 1.35rem;
                     text-align: center; background: var(--sidebar-hover); color: var(--sidebar-text); }
.sidebar .nav-badge.warn { background: var(--warning); color: var(--on-warning); }
.sidebar details { margin-top: .35rem; }
.sidebar summary { list-style: none; display: flex; align-items: center; justify-content: space-between; padding: .55rem 1.1rem .35rem; cursor: pointer;
                   color: var(--sidebar-header); font-size: .72rem; font-weight: 700; text-transform: uppercase; letter-spacing: .07em; }
.sidebar summary::-webkit-details-marker { display: none; }
.sidebar summary:hover { background: var(--sidebar-hover); }
.sidebar summary .chevron { color: var(--sidebar-chevron); transition: transform .15s; }
.sidebar details.has-active summary .chevron { color: var(--sidebar-chevron-active); }
.sidebar details[open] summary .chevron { transform: rotate(180deg); }
.sidebar a.nav-link:focus-visible, .sidebar summary:focus-visible { outline-color: var(--sidebar-icon-active); outline-offset: -2px; }
.sidebar-scrim { display: none; }
.content { flex: 1; min-width: 0; }
main.admin { max-width: 80rem; margin: 0 auto; padding: 1.5rem; overflow-x: auto; }

@media (max-width: 900px) {
    .nav-toggle { display: inline-grid; }
    .sidebar { position: fixed; z-index: 25; left: 0; top: var(--topbar-h); transform: translateX(-100%); transition: transform .2s ease; }
    /* shadow only while open: a closed off-canvas sidebar must not cast a grey band on the content edge */
    body.nav-open .sidebar { transform: none; box-shadow: 4px 0 18px var(--overlay); }
    body.nav-open .sidebar-scrim { display: block; position: fixed; inset: var(--topbar-h) 0 0 0; z-index: 20; background: var(--overlay); }
    .user-menu .who { display: none; }
    .topbar .brand-sub { display: none; }
    main.admin { padding: 1rem; }
}

/* ---- cards ---- */
.panel { border: 1px solid var(--border); border-radius: var(--radius); background: var(--card); padding: 1rem 1.2rem; margin-bottom: 1rem;
         box-shadow: 0 1px 2px color-mix(in srgb, var(--text) 6%, transparent); }
.panel > h2:first-child, .panel > h3:first-child { margin-top: 0; }

/* guest pages (login, TOTP) */
body.guest { display: flex; flex-direction: column; }
.guest-main { flex: 1; display: grid; place-items: center; padding: 2rem 0; }
.card { width: min(24rem, 92vw); padding: 2rem; border: 1px solid var(--border); border-radius: .75rem; background: var(--card);
        box-shadow: 0 2px 10px color-mix(in srgb, var(--text) 8%, transparent); }
.card.wide { width: min(34rem, 92vw); }
.card h1 { text-align: center; }

/* forms */
label { display: block; font-size: .9rem; margin: .9rem 0 .3rem; color: var(--text); }
input[type=text], input[type=email], input[type=password], input[type=search], input[type=date], input[type=number], input[type=url], select, textarea {
    width: 100%; padding: .55rem .7rem; border: 1px solid var(--border); border-radius: .4rem; background: var(--card); color: var(--text); font: inherit; }
input::placeholder, textarea::placeholder { color: var(--text-muted); opacity: .8; }
input:focus, select:focus, textarea:focus { outline: none; border-color: var(--primary); box-shadow: 0 0 0 3px color-mix(in srgb, var(--primary) 25%, transparent); }
input[type=checkbox], input[type=radio] { accent-color: var(--primary); }
input:disabled, select:disabled, textarea:disabled { background: var(--info-box); color: var(--text-muted); }
.btn { display: inline-block; padding: .55rem 1rem; border-radius: .4rem; border: 1px solid var(--primary); background: var(--primary); color: var(--on-primary);
       font: inherit; font-weight: 600; cursor: pointer; text-align: center; }
.btn:hover { text-decoration: none; background: color-mix(in srgb, var(--primary) 88%, var(--on-primary)); }
.btn.block { display: block; width: 100%; margin-top: 1.2rem; }
.btn.secondary { background: transparent; color: var(--secondary-text); border-color: var(--border); }
.btn.secondary:hover { background: var(--info-box); }
.btn.danger { background: var(--error); border-color: var(--error); color: var(--on-error); }
.btn.small { padding: .28rem .6rem; font-size: .85rem; }
.btn[disabled], .btn[disabled]:hover { opacity: .5; cursor: not-allowed; background: var(--primary); }
.btn.secondary[disabled], .btn.secondary[disabled]:hover { background: transparent; }
.row { display: flex; gap: .75rem; flex-wrap: wrap; align-items: end; } .row > * { flex: 1 1 10rem; }
/* style="flex:2|3" (basis 0) would let the main search field shrink to its longest word; keep it usable */
.row > [style*="flex:2"], .row > [style*="flex:3"], .row > [style*="flex: 2"], .row > [style*="flex: 3"] { min-width: min(14rem, 100%); }

/* flash / notices */
.errors { border: 1px solid var(--error); border-left-width: 4px; background: color-mix(in srgb, var(--error) 8%, var(--card)); color: var(--error-text);
          border-radius: .4rem; padding: .55rem .8rem; margin: 0 0 1rem; font-size: .9rem; }
.notice { border: 1px solid var(--border); border-left-width: 4px; border-left-color: var(--tint); background: var(--info-box); color: var(--text);
          border-radius: .4rem; padding: .55rem .8rem; margin: 0 0 1rem; font-size: .9rem; }
.notice.ok { border-color: var(--success); background: color-mix(in srgb, var(--success) 10%, var(--card)); color: var(--success-text); }
.notice.warn { border-color: var(--warning); background: color-mix(in srgb, var(--warning) 14%, var(--card)); color: var(--text); }
.notice.crit { border-color: var(--error); background: color-mix(in srgb, var(--error) 8%, var(--card)); color: var(--error-text); }
.divider { text-align: center; color: var(--text-muted); font-size: .85rem; margin: 1.2rem 0 .2rem; }
.qr { display: flex; justify-content: center; margin: 1rem 0; } .qr svg { background: var(--qr-background); padding: 8px; border-radius: .4rem; }
.codes { columns: 2; font-family: ui-monospace, monospace; padding: 1rem; border: 1px dashed var(--border); border-radius: .4rem; background: var(--info-box); }

/* zone quota banner: warning (yellow / orange) and critical (red) */
.banner { padding: .6rem 1.5rem; font-size: .9rem; border-bottom: 1px solid var(--border); }
.banner.warn { background: var(--warning); color: var(--on-warning); } .banner.warn a { color: var(--on-warning); }
.banner.crit { background: var(--error); color: var(--on-error); } .banner.crit a { color: var(--on-error); }
.banner a { text-decoration: underline; }
/* "Login as user" (DESIGN.md §8.3): always visible below the top bar */
.banner.impersonation { position: sticky; top: var(--topbar-h); z-index: 25; color: var(--on-warning);
                        /* hatched, so it never blends into the top bar (dark theme: warning = top bar orange) */
                        background: repeating-linear-gradient(-45deg, var(--warning) 0 18px, color-mix(in srgb, var(--warning) 80%, #000) 18px 36px);
                        border-top: 2px solid color-mix(in srgb, var(--warning) 60%, #000); border-bottom: 2px solid var(--error);
                        display: flex; flex-wrap: wrap; align-items: center; gap: .4rem .8rem; }
.banner.impersonation .imp-text { flex: 1 1 16rem; min-width: 0; overflow-wrap: anywhere;
                                  text-shadow: 0 0 4px var(--warning), 0 0 2px var(--warning); }
@media (max-width: 900px) { .banner.impersonation { padding: .5rem 1rem; } }
.banner.impersonation form.inline { display: inline; margin: 0; }

/* tables */
table { width: 100%; border-collapse: separate; border-spacing: 0; font-size: .9rem; background: var(--card); color: var(--text);
        border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; }
th, td { text-align: left; padding: .5rem .7rem; border-bottom: 1px solid var(--border); vertical-align: top; }
tr:last-child > td { border-bottom: 0; }
th { font-weight: 600; color: var(--text-muted); font-size: .78rem; text-transform: uppercase; letter-spacing: .04em; background: var(--info-box); }
tbody tr:hover > td, table > tr:hover > td { background: color-mix(in srgb, var(--primary) 4%, transparent); }
.panel table { box-shadow: none; }

/* badges (push / sync state, roles ...) */
.badge { display: inline-block; padding: .05rem .5rem; border-radius: 1rem; border: 1px solid var(--border); font-size: .78rem; color: var(--text); background: var(--card); white-space: nowrap; }
.badge.ok { border-color: var(--success); color: var(--success-text); background: color-mix(in srgb, var(--success) 10%, var(--card)); }
.badge.warn { border-color: var(--warning); color: var(--warning-text); background: color-mix(in srgb, var(--warning) 12%, var(--card)); }
.badge.crit { border-color: var(--error); color: var(--error-text); background: color-mix(in srgb, var(--error) 8%, var(--card)); }
.badge.running { border-color: var(--primary); color: var(--primary-text); background: color-mix(in srgb, var(--primary) 10%, var(--card)); }
.bar { height: .8rem; border-radius: .4rem; background: var(--info-box); border: 1px solid var(--border); overflow: hidden; margin: .4rem 0; }
.bar > span { display: block; height: 100%; background: var(--success); } .bar.warn > span { background: var(--warning); } .bar.crit > span { background: var(--error); }
.pager { margin-top: 1rem; display: flex; gap: .75rem; }
details pre { white-space: pre-wrap; word-break: break-all; font-size: .8rem; margin: .3rem 0; }
summary { cursor: pointer; }

/* IP overview */
td.num, th.num { text-align: right; font-variant-numeric: tabular-nums; }
.badge.src-tos { border-color: var(--primary); color: var(--primary-text); } .badge.src-os { border-color: var(--topbar); color: var(--warning-text); }
.badge.src-manual { border-color: var(--success); color: var(--success-text); }
.st { display: inline-block; min-width: 4.5rem; text-align: center; }
.st-used { border-color: var(--success); color: var(--success-text); } .st-reserved { border-color: var(--warning); color: var(--warning-text); } .st-free { color: var(--text-muted); }
tr.free td { color: var(--text-muted); } tr.conflict td { background: color-mix(in srgb, var(--error) 8%, var(--card)); }
.ipam td { padding: .35rem .6rem; } .ipam .src { font-size: .7rem; color: var(--text-muted); text-transform: uppercase; letter-spacing: .03em; }
.stats { display: flex; gap: 1.5rem; flex-wrap: wrap; } .stats div b { display: block; font-size: 1.3rem; }
/* IP pages: TenantOS-style popup editing of rDNS and description (public/js/ipam-edit.js) */
.ipam-edit { background: none; border: 0; padding: 0; margin: 0; font: inherit; color: inherit; text-align: left; cursor: pointer; display: inline-flex; align-items: baseline; gap: .3rem; }
.ipam-edit:hover span:not(.ipam-none), .ipam-edit:focus-visible span:not(.ipam-none) { text-decoration: underline dotted; }
.ipam-edit:focus-visible { outline: 2px solid var(--primary-text); outline-offset: 2px; border-radius: .2rem; }
.ipam-pencil { color: var(--text-muted); flex: none; position: relative; top: 1px; } .ipam-edit:hover .ipam-pencil { color: var(--primary-text); }
.ipam-none { color: var(--error-text); font-style: italic; text-decoration: underline; }
.ipam-none.ro { text-decoration: none; cursor: help; } .ipam-ro[title] { cursor: help; }
.ipam-modal { border: 1px solid var(--border); border-radius: .6rem; background: var(--card); color: var(--text); padding: 1.2rem 1.4rem; width: min(32rem, 92vw);
              box-shadow: 0 12px 40px var(--overlay); }
.ipam-modal::backdrop { background: var(--overlay); }
.ipam-modal h3 { margin: 0 0 .8rem; } .ipam-modal input, .ipam-modal select, .ipam-modal textarea { width: 100%; }
.ipam-modal p { margin: .4rem 0 0; } .ipam-modal p:empty { display: none; } .ipam-modal .err { color: var(--error-text); }
.ipam-modal .warn { color: var(--text); background: color-mix(in srgb, var(--warning) 14%, var(--card)); border-left: 3px solid var(--warning); padding: .3rem .5rem; border-radius: .2rem; }
.ipam-modal .ok { color: var(--success-text); }
.ip-assign-modal { width: min(40rem, 94vw); }
.ip-assign-list { max-height: 14rem; overflow-y: auto; border: 1px solid var(--border); border-radius: .3rem; margin-top: .3rem; }
.ip-assign-option { display: block; width: 100%; text-align: left; background: none; border: 0; border-bottom: 1px solid var(--border); padding: .35rem .5rem; color: var(--text); cursor: pointer; font: inherit; }
.ip-assign-option:hover, .ip-assign-option.selected { background: color-mix(in srgb, var(--accent, #3b82f6) 14%, var(--card)); }
.ip-assign-option .badge { margin-left: .4rem; }
.ip-assign-row { display: flex; justify-content: space-between; align-items: center; gap: .5rem; padding: .2rem 0; }
.ipam-modal-actions { margin-top: 1rem; display: flex; gap: .5rem; justify-content: flex-end; }

/* landing page */
.landing { min-height: 100vh; display: flex; flex-direction: column; }
.landing .guest-main .card { text-align: center; }
.landing h1 { font-size: 2rem; letter-spacing: -.02em; margin-bottom: 1.5rem; }

/* dashboard (resources/views/admin/dashboard.blade.php) */
.dash-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 24rem), 1fr)); gap: 1rem; align-items: start; }
.dash-grid > .panel { margin-bottom: 0; min-width: 0; }
.dash-grid h2 { margin-top: 0; display: flex; align-items: baseline; gap: .5rem; flex-wrap: wrap; }
.dash-grid h2 .more { margin-left: auto; font-size: .8rem; font-weight: normal; }
.dash-grid h3 { margin: 1rem 0 .4rem; }
.kv { display: grid; grid-template-columns: 1fr auto; gap: .3rem 1rem; margin: 0; }
@media (min-width: 600px) { .kv dt { white-space: nowrap; } }
.kv dt { color: var(--text-muted); } .kv dd { margin: 0; text-align: right; font-variant-numeric: tabular-nums; }
.hbars { list-style: none; margin: 0; padding: 0; }
.hbars li { display: grid; grid-template-columns: 4rem 1fr 4rem; gap: .6rem; align-items: center; font-size: .85rem; }
.hbars .bar { margin: .2rem 0; } .hbars .num { text-align: right; font-variant-numeric: tabular-nums; }
.dash-line { padding: .25rem 0; border-bottom: 1px solid var(--border); } .dash-line:last-of-type { border-bottom: 0; }
.dash-busiest .bar { margin: .2rem 0 0; min-width: 5rem; }
.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; }
/* Quellen-Sync: live status pill + "Jetzt synchronisieren" (public/js/source-sync.js) */
.source-sync td.sync-status .badge { margin: .1rem .2rem .1rem 0; }
.source-sync td.sync-action { text-align: right; white-space: nowrap; width: 1%; }
.source-sync td.sync-action form { margin: 0; }
.source-sync-foot { display: flex; align-items: center; justify-content: space-between; gap: .5rem 1rem; flex-wrap: wrap; }
.source-sync-foot p { margin: 0; flex: 1 1 14rem; }
.source-sync-foot form { margin: 0 0 0 auto; }
.source-sync [data-sync-msg] { margin: .5rem 0; }
/* Phones: one block per source (name + button, status, last success), no fourth column off the panel. */
@media (max-width: 640px) {
    .source-sync table, .source-sync tbody { display: block; }
    .source-sync tr.sync-head { display: none; }
    .source-sync tr[data-sync-row] { display: grid; grid-template-columns: 1fr auto; align-items: center; gap: .35rem .6rem; padding: .6rem .7rem; border-bottom: 1px solid var(--border); }
    .source-sync tr[data-sync-row]:last-child { border-bottom: 0; }
    .source-sync tr[data-sync-row] > td { display: block; padding: 0; border: 0; }
    .source-sync td.sync-name { font-weight: 600; }
    .source-sync td.sync-action { grid-column: 2; grid-row: 1; width: auto; }
    .source-sync td.sync-status, .source-sync td.sync-last { grid-column: 1 / -1; }
    .source-sync td.sync-last { color: var(--text-muted); font-size: .85rem; }
    .source-sync td.sync-last::before { content: attr(data-label) ": "; }
}

/* rDNS-Resets freigeben: current -> proposed */
.table-scroll { overflow-x: auto; }
/* Unbekannte rDNS: long IPv6 addresses and PTR names wrap instead of widening the table past 1440 px */
.untracked-ptrs td.mono { overflow-wrap: anywhere; word-break: break-word; min-width: 8rem; max-width: 22rem; }
.rdns-diff del { color: var(--error-text); }
.rdns-diff ins { color: var(--success-text); text-decoration: none; font-weight: 600; }
