/*! frb-hub.css — the portal hub pages, one copy.
 *
 * The sixteen portal hub pages carried this byte-identical, 181-line block
 * each. Not similar: identical, to the byte. Sixteen copies of a theme engine
 * means a colour fixed on one hub is fixed on one hub, and the other fifteen
 * keep the old value until somebody remembers them -- which is the mechanism
 * behind every 'this token is declared 473 times' number in this design system.
 *
 * Linked from the same position the <style> occupied, so the cascade order is
 * unchanged; verified by snapshotting the computed style of all 2,508 classed
 * nodes on these pages before and after and requiring zero differences.
 */

:root {
    --glass-border: 1px solid rgba(255, 255, 255, 0.08);
    --card-shadow: 0 10px 30px -10px rgba(0,0,0,0.5);
    --transition-speed: 0.3s;
}
/* --- THEME ENGINE (STRICT CSV COMPLIANCE) --- */
body.theme-midnight {
    --bg-gradient: radial-gradient(circle at 50% 0%, #1a1a1a 0%, #000000 100%);
    --text-primary: #f8fafc;
    --text-secondary: #9ca3af;
    --accent-primary: #d4af37; /* Gold */
    --accent-glow: rgba(212, 175, 55, 0.3);
    --panel-bg: rgba(10, 10, 10, 0.8);
    --card-bg: rgba(30, 41, 59, 0.4);
}
body.theme-ocean {
    --bg-gradient: radial-gradient(circle at 50% 0%, #0a2540 0%, #000814 100%);
    --text-primary: #e5effa;
    --text-secondary: #8fa6bf;
    --accent-primary: #4fa3d1; /* Cyan */
    --accent-glow: rgba(79, 163, 209, 0.25);
    --panel-bg: rgba(8, 18, 32, 0.85);
    --card-bg: rgba(15, 23, 42, 0.5);
}
body.theme-sunset {
    --bg-gradient: radial-gradient(circle at 50% 0%, #434343 0%, #000000 100%);
    --text-primary: #fff1e6;
    --text-secondary: #dcb3a8;
    --accent-primary: #ff9f43; /* Orange */
    --accent-glow: rgba(255, 159, 67, 0.25);
    --panel-bg: rgba(30, 30, 30, 0.85);
    --card-bg: rgba(45, 45, 45, 0.5);
}
body.theme-forest {
    --bg-gradient: radial-gradient(circle at 50% 0%, #1a2e28 0%, #050f0c 100%);
    --text-primary: #e8f5e9;
    --text-secondary: #a5d6a7;
    --accent-primary: #66ff66; /* Green */
    --accent-glow: rgba(102, 255, 102, 0.2);
    --panel-bg: rgba(13, 27, 30, 0.85);
    --card-bg: rgba(20, 40, 40, 0.5);
}
/* --- LIGHT MODE OVERRIDES --- */
body.light-mode {
    --bg-gradient: radial-gradient(circle at 50% 10%, #f8fafc 0%, #e2e8f0 100%);
    --text-primary: #0f172a;
    --text-secondary: #55637a;
    --panel-bg: rgba(255, 255, 255, 0.92);
    --glass-border: 1px solid rgba(15, 23, 42, 0.12);
    --card-bg: #ffffff;
    --card-shadow: 0 20px 40px -10px rgba(0,0,0,0.1);
}
body.light-mode.theme-midnight { --accent-primary: #bfa039; }
body.light-mode.theme-ocean { --accent-primary: #0077b6; }
body.light-mode.theme-sunset { --accent-primary: #e67e22; }
body.light-mode.theme-forest { --accent-primary: #059669; }
body {
    font-family: 'Outfit', sans-serif;
    background-image: var(--bg-gradient);
    background-attachment: fixed;
    color: var(--text-primary);
    min-height: 100vh; margin: 0;
    display: flex; flex-direction: column;
    overflow-x: hidden;
    opacity: 0; 
    animation: fadeInPage 0.2s forwards;
}
@keyframes fadeInPage { to { opacity: 1; } }
/* --- NAVIGATION --- */
.navbar-glass {
    padding: 20px 40px;
    border-bottom: var(--glass-border);
    background: var(--panel-bg);
    backdrop-filter: blur(15px);
    display: flex; justify-content: space-between; align-items: center;
    position: sticky; top: 0; z-index: 100;
}
.brand-logo { 
    font-family: 'JetBrains Mono', monospace; font-weight: 800; 
    color: var(--accent-text, var(--accent-primary)); font-size: 24px; cursor: pointer; text-decoration: none;
}
.breadcrumbs {
    font-size: 13px; color: var(--text-secondary); display: flex; align-items: center; gap: 8px;
}
.breadcrumbs a { color: var(--text-secondary); text-decoration: none; transition: 0.2s; }
.breadcrumbs a:hover { color: var(--text-primary); }
.breadcrumbs .active { color: var(--accent-text, var(--accent-primary)); font-weight: 600; }
/* --- HEADER --- */
.module-header {
    padding: 40px 40px 20px 40px;
    background: linear-gradient(to bottom, rgba(255,255,255,0.02), transparent);
    border-bottom: var(--glass-border);
    display: flex; justify-content: space-between; align-items: end;
}
/* --- GRID SYSTEM (MOSAIC) --- */
.app-grid {
    display: grid; gap: 20px; padding: 40px;
    transition: all 0.4s ease;
    max-width: 1600px; margin: 0 auto; width: 100%;
    grid-template-columns: repeat(4, 1fr); 
    grid-auto-rows: minmax(240px, auto); /* fixed 240px + overflow:hidden
       silently cut the last lines off longer tiles */ 
    grid-auto-flow: dense;
}
@media (max-width: 1200px) { .app-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 768px) {
    .app-grid { grid-template-columns: 1fr; }
    /* The hero spans two columns. At one explicit column that span
       creates an IMPLICIT second column, and every alternate tile
       lands in it about 52px wide. Reset the spans with the grid. */
    /* .app-grid prefix: the base `.card-hero` rule is LATER in this
       stylesheet, so at equal specificity it would win. */
    .app-grid .card-hero, .app-grid .card-wide { grid-column: auto; }
}
/* --- CARD STYLES --- */
.app-card {
    background: var(--card-bg); 
    border: var(--glass-border);
    border-radius: 20px; 
    padding: 25px; 
    position: relative;
    display: flex; flex-direction: column; 
    text-decoration: none;
    transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);
    overflow: hidden;
    backdrop-filter: blur(10px);
    box-shadow: var(--card-shadow);
}
.app-card:hover { 
    transform: translateY(-5px); 
    border-color: var(--accent-primary); 
    background: rgba(30, 41, 59, 0.7);
}
body.light-mode .app-card:hover { background: #fff; box-shadow: 0 10px 40px -10px rgba(0,0,0,0.15); }
/* Hero Card */
.card-hero {
    grid-column: span 2; grid-row: span 2; 
    background: linear-gradient(135deg, rgba(30, 41, 59, 0.8), rgba(15, 23, 42, 0.9));
    border: 1px solid var(--accent-primary);
}
body.light-mode .card-hero {
    background: linear-gradient(135deg, #fff, #f1f5f9);
}
.card-hero .app-icon { width: 80px; height: 80px; font-size: 32px; background: var(--accent-primary); color: #000; }
body.light-mode .card-hero .app-icon { color: #fff; }
.card-hero .app-title { font-size: 28px; margin-bottom: 15px; }
.card-hero .app-desc { font-size: 16px; max-width: 80%; }
/* Wide Card */
.card-wide { grid-column: span 2; }
.app-icon {
    width: 50px; height: 50px; 
    background: rgba(255,255,255,0.05); 
    color: var(--accent-text, var(--accent-primary));
    border-radius: 14px; 
    display: flex; align-items: center; justify-content: center;
    font-size: 22px; margin-bottom: 15px;
    box-shadow: inset 0 0 20px rgba(0,0,0,0.3);
    transition: 0.3s;
}
body.light-mode .app-icon { background: rgba(0,0,0,0.05); box-shadow: none; }
.app-title { color: var(--text-primary); font-weight: 700; font-size: 18px; margin-bottom: 8px; }
/* NO `opacity` — --text-secondary IS the dimmed colour, and multiplying it by
   0.8 dims it twice. Measured from the pixels across the hub pages, every card
   description in light mode came in at 2.13–2.16:1; the token on its own clears
   the same ground comfortably. This one line is seven elements on each of eight
   hub pages. */
.app-desc { color: var(--text-secondary); font-size: 13px; line-height: 1.5; margin-bottom: 0; }
/* Badges */
.status-badge { 
    position: absolute; top: 20px; right: 20px; 
    font-size: 9px; font-weight: 800; 
    padding: 4px 10px; border-radius: 20px; 
    text-transform: uppercase; letter-spacing: 1px;
}
.badge-live { background: var(--success-bg); color: var(--success); border: 1px solid var(--success); }
.badge-beta { background: var(--warning-bg); color: var(--warning); border: 1px solid var(--warning); }
.badge-soon { background: rgba(255, 255, 255, 0.03); color: #94a3b8; border: 1px solid rgba(255,255,255,0.05); }
body.light-mode .badge-soon { background: rgba(0,0,0,0.05); color: #64748b; border: 1px solid rgba(0,0,0,0.1); }
.locked { cursor: default; opacity: 0.6; filter: grayscale(0.8); }
.app-card:hover.locked { filter: grayscale(0.2); opacity: 1; border-color: var(--glass-border); }
.cmd-arrow {
    position: absolute; bottom: 25px; right: 25px;
    color: var(--accent-text, var(--accent-primary)); opacity: 0; transition: 0.3s;
}
.app-card:hover .cmd-arrow { opacity: 1; transform: translateX(5px); }
