/* weircon portal — app-specific glue on top of the shared weirsoe-theme. The theme (assets.weircon.dk/css/weirsoe-theme.css) owns the look: tokens, chrome, cards, buttons, inputs, palette. This file is ONLY the portal's own bits — self-hosted font, base typography, and widgets the theme doesn't have (favourite star, skeletons, ops slots). Everything here uses theme tokens. */ /* Self-hosted Inter (pixel-exact) — drives the theme's sans token. */ @font-face { font-family: "Inter Variable"; font-style: normal; font-weight: 100 900; font-display: swap; src: url("/static/fonts/inter.woff2") format("woff2"); } :root { --wt-font-sans: "Inter Variable", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; } * { box-sizing: border-box; } body { margin: 0; min-height: 100vh; display: flex; flex-direction: column; -webkit-font-smoothing: antialiased; } .wt-main { flex: 1; } a { color: inherit; } /* app typography */ h1 { font-size: 2.2rem; letter-spacing: -.025em; margin: .6rem 0 .35rem; font-weight: 800; } h2 { font-size: .8rem; text-transform: uppercase; letter-spacing: .14em; color: var(--color-muted); margin: 2.6rem 0 1rem; font-weight: 600; } code { background: var(--color-surface-2); padding: .12em .42em; border-radius: .35rem; font-size: .85em; font-family: var(--wt-font-mono); } .wt-mono { font-family: var(--wt-font-mono); } /* bare form controls opt into the theme's input look */ input:not([type=checkbox]):not([type=radio]):not([type=submit]):not([type=button]), textarea, select { width: 100%; background: var(--color-surface-2); border: 1px solid var(--color-border); color: var(--color-text); border-radius: var(--wt-radius-sm); padding: .5rem .65rem; font: inherit; } input:focus, textarea:focus, select:focus { outline: none; border-color: var(--color-accent); } textarea { min-height: 5rem; resize: vertical; } label { display: block; } /* nav identity line */ .wt-nav .who { color: var(--color-muted); font-size: .9rem; } /* favourite star + click-overlay on a tile */ .fav { position: absolute; top: .55rem; right: .6rem; z-index: 2; width: 1.7rem; height: 1.7rem; border-radius: .5rem; border: 0; background: transparent; color: var(--color-border); cursor: pointer; font-size: 1.05rem; line-height: 1; padding: 0; transition: color .15s, transform .15s; } .fav:hover { color: var(--color-muted); transform: scale(1.15); } .fav.on { color: #f5c518; } /* skeleton placeholders */ .sk { display: inline-block; background: var(--color-surface-2); border-radius: 5px; } /* selectable card — link + dim variants (admin → users) */ a.wt-select-card { text-decoration: none; color: inherit; } a.wt-select-card .unav { flex: 0 0 auto; color: var(--color-accent); opacity: .7; } .wt-select-card.dim { opacity: .55; } /* generic show/hide hooks used by the filter JS */ [hidden] { display: none !important; } .hidden { display: none !important; } /* ops — random-proxy egress slots */ .slot { background: color-mix(in srgb, var(--color-surface) 70%, transparent); border: 1px solid var(--color-border); border-radius: .9rem; padding: .8rem .9rem; } .slot.next { border-color: #f5a623; box-shadow: 0 0 0 1px color-mix(in srgb, #f5a623 40%, transparent); } .slot-top { display: flex; justify-content: space-between; align-items: center; margin-bottom: .35rem; } .slot-id { font-weight: 700; color: var(--color-muted); font-size: .85rem; } .slot-state { font-size: .72rem; border-radius: 999px; padding: .05rem .5rem; border: 1px solid var(--color-border); color: var(--color-muted); } .slot-state.live { color: var(--color-good); border-color: color-mix(in srgb, var(--color-good) 40%, transparent); } .slot-state.busy { color: #f5a623; border-color: color-mix(in srgb, #f5a623 40%, transparent); } .slot-state.down { color: var(--color-bad); border-color: color-mix(in srgb, var(--color-bad) 40%, transparent); } .slot-next { color: #f5a623; font-size: .74rem; margin-top: .35rem; } /* --------------------------------------------------------------------------- Legacy token aliases — the admin-heavy pages (ops/media/access) keep their own page-specific widget CSS (vbadge, slot, vtable, mbadge, sw/fld/setgrid, segmented, pager, clist, crow, modal…) which references the portal's old token names. Map those onto the theme tokens so the THEME still drives every colour/value — change the theme and these pages follow. --------------------------------------------------------------------------- */ :root { --bg: var(--color-bg); --surface: var(--color-surface); --surface2: var(--color-surface-2); --border: var(--color-border); --text: var(--color-text); --muted: var(--color-muted); --accent: var(--color-accent); --accent2: var(--color-accent-2); --ok: var(--color-good); } /* dashboard — minecraft server status dot */ .mcdot { display:inline-block; width:.55rem; height:.55rem; border-radius:50%; margin-right:.4rem; } .mcdot.run { background:var(--color-good); box-shadow:0 0 6px color-mix(in srgb,var(--color-good) 50%,transparent); } .mcdot.off { background:var(--color-muted); } .mcdot.warn { background:#f5c518; } .mcdot.err { background:var(--color-bad); } /* theme tag variants used by the access pages */ .wt-tag.open { color:var(--color-good); border-color:color-mix(in srgb,var(--color-good) 40%,transparent); background:color-mix(in srgb,var(--color-good) 10%,transparent); } .wt-tag.muted { color:var(--color-muted); } /* destructive button (access-edit confirm) */ .wt-btn--danger { background:var(--color-bad); border-color:transparent; color:#fff; font-weight:650; } .wt-btn--danger:hover { filter:brightness(1.08); } /* --------------------------------------------------------------------------- Legacy component classes — the reconciled admin/dashboard templates still use the portal's original class names (.card/.btn/.stat/.grid/.filter/.ucard…) together with their own page-local widget CSS. Defined here on the THEME tokens (via the aliases above) so they render in the shared design language without touching that markup/JS. (Public/core pages already use .wt-*.) Follow-up: migrate these pages to .wt-* and delete this block. --------------------------------------------------------------------------- */ .lead { color:var(--muted); font-size:1.05rem; max-width:46rem; } .filter { margin:1.4rem 0 .2rem; position:relative; max-width:22rem; } .filter input { padding-left:2.2rem; } .filter .mag { position:absolute; left:.7rem; top:50%; transform:translateY(-50%); color:var(--muted); } .grid { display:grid; gap:.9rem; grid-template-columns:repeat(auto-fill, minmax(220px, 1fr)); margin-top:1rem; } .card { display:flex; flex-direction:column; min-height:7.25rem; height:100%; position:relative; background:color-mix(in srgb, var(--surface) 70%, transparent); border:1px solid var(--border); border-radius:1rem; padding:1.1rem 1.15rem; text-decoration:none; color:inherit; transition:border-color .18s ease, transform .18s ease, background .18s ease; } a.card:hover, .card:hover { border-color:var(--accent); transform:translateY(-3px); background:color-mix(in srgb, var(--surface) 92%, transparent); } .card.hidden { display:none; } .card .head { display:flex; align-items:center; gap:.65rem; } .card .ico { flex:0 0 auto; width:2.1rem; height:2.1rem; border-radius:.6rem; display:grid; place-items:center; font-weight:700; font-size:1rem; background:color-mix(in srgb, var(--accent) 16%, transparent); color:var(--accent); overflow:hidden; } .card .ico img { width:100%; height:100%; object-fit:contain; } .card .name { font-weight:600; letter-spacing:-.01em; line-height:1.25; } .card .sub { color:var(--muted); font-size:.86rem; margin-top:.6rem; flex:1; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; } .card .go { color:var(--accent); font-size:.8rem; margin-top:.7rem; opacity:.85; } .btn { display:inline-block; background:var(--accent); color:var(--color-accent-ink); font-weight:600; text-decoration:none; padding:.6rem 1.15rem; border-radius:.7rem; border:0; cursor:pointer; font:inherit; font-size:.95rem; } .btn:hover { filter:brightness(1.08); } .btn.secondary { background:var(--surface2); color:var(--text); border:1px solid var(--border); } table { width:100%; border-collapse:collapse; } th, td { border:1px solid var(--border); padding:.45rem .55rem; text-align:left; } th { color:var(--muted); font-weight:600; font-size:.8rem; text-transform:uppercase; letter-spacing:.06em; } .flash { background:color-mix(in srgb, var(--accent) 12%, transparent); border:1px solid var(--accent); color:var(--accent); border-radius:.7rem; padding:.65rem .95rem; margin:1rem 0; font-size:.9rem; } .err { background:color-mix(in srgb, #f5a623 14%, transparent); border:1px solid #f5a623; color:#f5a623; border-radius:.7rem; padding:.65rem .95rem; margin:1rem 0; font-size:.9rem; } .muted { color:var(--muted); } .stat { background:color-mix(in srgb, var(--surface) 70%, transparent); border:1px solid var(--border); border-radius:1rem; padding:1.3rem; } .stat .n { font-size:2.1rem; font-weight:800; letter-spacing:-.02em; } .ucards { display:grid; gap:.55rem; grid-template-columns:repeat(auto-fill,minmax(15rem,1fr)); margin-top:.6rem; } .ucard { position:relative; display:flex; align-items:center; gap:.6rem; padding:.55rem .7rem; border:1px solid var(--border); border-radius:.8rem; background:color-mix(in srgb,var(--surface) 70%,transparent); cursor:pointer; min-width:0; transition:border-color .15s, background .15s; } .ucard:hover { border-color:var(--accent); } .ucard input { position:absolute; opacity:0; pointer-events:none; } .ucard:has(input:checked) { border-color:var(--accent); background:color-mix(in srgb,var(--accent) 12%,transparent); } .ucard .uini { flex:0 0 auto; width:1.9rem; height:1.9rem; border-radius:.5rem; display:grid; place-items:center; font-weight:700; font-size:.85rem; background:color-mix(in srgb,var(--accent) 16%,transparent); color:var(--accent); } .ucard .ubody { min-width:0; flex:1; } .ucard .uname { font-weight:600; font-size:.9rem; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; } .ucard .usub { color:var(--muted); font-size:.78rem; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; } .ucard .uchk { flex:0 0 auto; width:1.25rem; height:1.25rem; border:1.5px solid var(--border); border-radius:.35rem; display:grid; place-items:center; color:transparent; font-size:.8rem; font-weight:700; } .ucard:has(input:checked) .uchk { background:var(--accent); border-color:var(--accent); color:var(--color-accent-ink); } .ucard.hidden { display:none; } /* Tabeller og andet bredt indhold må aldrig give siden vandret scroll på en telefon. Standard for alle sider: på smalle skærme bliver en tabel sit eget rulleområde, og lange ord/nøgler brydes. (Ops-siden har desuden sin egen kort-visning.) */ .wt-main { overflow-wrap: anywhere; min-width: 0; } @media (max-width: 760px) { .wt-main table { display: block; max-width: 100%; overflow-x: auto; -webkit-overflow-scrolling: touch; } .wt-main table td, .wt-main table th { overflow-wrap: normal; } }