@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Outfit:wght@400;500;600;700;800&display=swap');

:root {
    color-scheme: dark;
    --bg: #07090e;
    --work-bg: #0b0f19;
    --panel: rgba(17, 24, 39, 0.7);
    --panel-solid: #111827;
    /* Panel zadokowany przy krawedzi lezy NA scenie i nie da sie go odsunac,
       wiec musi dac przez siebie zobaczyc model. Pelna krycie wraca pod
       kursorem — do czytania i klikania. */
    --panel-docked: rgba(17, 24, 39, 0.82);
    --canvas: #090d16;
    --line: rgba(255, 255, 255, 0.07);
    --line-strong: rgba(255, 255, 255, 0.15);
    --text: #f3f4f6;
    --muted: #9ca3af;
    --soft: rgba(255, 255, 255, 0.03);
    --accent: #3b82f6;
    --accent-dark: #1d4ed8;
    --accent-soft: rgba(59, 130, 246, 0.15);
    /* Tekst NA akcencie — w obu motywach bialy, ale przez token, zeby
       przycisk glowny nie mial zakodowanego koloru. */
    --accent-ink: #ffffff;
    --danger: #ef4444;
    --danger-soft: rgba(239, 68, 68, 0.15);
    /* Ostrzezenie — stan posredni miedzy spokojem a bledem. Pasek zajetosci
       chmury potrzebuje trzech stanow: jest miejsce / konczy sie / nie ma. */
    --warn: #f59e0b;
    --warn-soft: rgba(245, 158, 11, 0.15);
    --shadow-sm: 0 2px 8px rgba(0, 0, 0, 0.4);
    --shadow-md: 0 12px 32px rgba(0, 0, 0, 0.5);
    /* Uzywane przez .menu-content i .modal-card. Nie byly zadeklarowane,
       wiec obie warstwy renderowaly sie BEZ cienia i zlewaly z tlem. */
    --shadow-lg: 0 18px 48px rgba(0, 0, 0, 0.55);
    --shadow-2xl: 0 28px 72px rgba(0, 0, 0, 0.65);
    --input-bg: rgba(255, 255, 255, 0.05);
    --hover-bg: rgba(255, 255, 255, 0.06);
    --hover-border: rgba(255, 255, 255, 0.15);
    --font-mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, monospace;
    --glass-bg: rgba(22, 30, 49, 0.65);
    --glass-border: rgba(255, 255, 255, 0.08);
    --bg-card: #111827;
    --font-family: 'Outfit', 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
}

:root[data-theme="light"] {
    /* Motyw "papier" — paleta z plansz projektowych. Cieple szarosci
       zamiast niebieskich, akcent teal, cienie brazowe a nie czarne. */
    color-scheme: light;
    --bg: #f0ece4;
    --work-bg: #e6e1d8;
    --panel: rgba(255, 253, 250, 0.88);
    --panel-solid: #fffdfa;
    --panel-docked: rgba(255, 253, 250, 0.86);
    --canvas: #f7f4ee;
    --line: #e6e1d8;
    --line-strong: #ded8cd;
    --text: #2b2926;
    --muted: #7a746c;
    --soft: rgba(60, 50, 35, 0.045);
    --accent: #23676f;
    --accent-dark: #1b525a;
    --accent-soft: #e7f2f2;
    --accent-ink: #ffffff;
    --danger: #c96a5e;
    --danger-soft: rgba(201, 106, 94, 0.12);
    --warn: #b8842b;
    --warn-soft: rgba(184, 132, 43, 0.14);
    --shadow-sm: 0 1px 3px rgba(60, 50, 35, 0.10), 0 1px 2px rgba(60, 50, 35, 0.06);
    --shadow-md: 0 10px 30px rgba(60, 50, 35, 0.12), 0 1px 8px rgba(60, 50, 35, 0.06);
    --shadow-lg: 0 16px 44px rgba(60, 50, 35, 0.16), 0 2px 12px rgba(60, 50, 35, 0.08);
    --shadow-2xl: 0 28px 68px rgba(80, 62, 34, 0.22), 0 4px 16px rgba(80, 62, 34, 0.10);
    --glass-bg: rgba(255, 253, 250, 0.88);
    --glass-border: #e6e1d8;
    --bg-card: #fffdfa;
    --input-bg: #f4f1ea;
    --hover-bg: rgba(60, 50, 35, 0.055);
    --hover-border: rgba(60, 50, 35, 0.16);
}

* {
    box-sizing: border-box;
}

html,
body {
    height: 100%;
    margin: 0;
}

body {
    overflow: hidden;
    background: var(--bg);
    color: var(--text);
    font-family: var(--font-family);
    user-select: none;
    -webkit-font-smoothing: antialiased;
}

button,
input {
    font: inherit;
}

/* Scrollbar styling */
::-webkit-scrollbar {
    width: 6px;
    height: 6px;
}
::-webkit-scrollbar-track {
    background: transparent;
}
::-webkit-scrollbar-thumb {
    background: var(--line-strong);
    border-radius: 3px;
}
::-webkit-scrollbar-thumb:hover {
    background: var(--muted);
}

button {
    min-height: 36px;
    border: 1px solid var(--glass-border);
    border-radius: 8px;
    background: var(--soft);
    color: var(--text);
    cursor: pointer;
    font-weight: 500;
    transition: all 150ms cubic-bezier(0.4, 0, 0.2, 1);
}

button:hover:not(:disabled) {
    background: var(--hover-bg);
    border-color: var(--hover-border);
    box-shadow: var(--shadow-sm);
}

/* WCISNIECIE MUSI BYC WIDAC. Samo scale(0.98) gubilo sie przy kazdym
   kliknieciu, a bialy hover z motywu ciemnego na papierowym tle nie
   zmienial nic — na jasnym motywie przycisk wygladal na martwy. */
button:active:not(:disabled) {
    transform: scale(0.98);
    background: var(--accent-soft);
    border-color: var(--accent);
    color: var(--accent);
}

button:disabled {
    cursor: not-allowed;
    opacity: 0.4;
}

.app-shell {
    display: grid;
    /* topbar / wiersz wstazki / workspace. Wstazka jest
       rodzenstwem topbara, nie jego dzieckiem — delegacja zdarzen wewnatrz
       .topbar umieralaby na stopPropagation z .menu-trigger. */
    grid-template-rows: 44px 122px 1fr;
    /* JEDNA KOLUMNA NIE SZERSZA NIZ OKNO. Domyslna kolumna `auto` bierze
       szerokosc z tresci, a wstazka ma ~1300 px — przy wezszym oknie cala
       powloka wystawala w prawo i znikaly gizmo, konto i prawe panele. */
    grid-template-columns: minmax(0, 1fr);
    height: 100vh;
    overflow: hidden;
    background: var(--bg);
}

/* WIERSZ WSTAZKI ZNIKA RAZEM ZE WSTAZKA.
   Na czas operacji 3D wstazka sie chowa (parametry maja wlasny panel), ale
   wiersz siatki zostawal — 122 px bialego pasa nad plotnem, przez ktory
   plywajaca karta operacji wygladala, jakby chowala sie pod czyms.
   Reguly nie wolno przeniesc WYZEJ niz .app-shell: markup.test.js czyta
   pierwsze `grid-template-rows` w pliku jako wymiary powloki. */
.app-shell.bez-wstazki { grid-template-rows: 44px 0 1fr; }
.app-shell.bez-wstazki > .ribbon-row { overflow: hidden; border-bottom: none; }

.topbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    min-width: 0;
    padding: 4px 10px;
    border-bottom: 1px solid var(--line);
    background: var(--panel);
    backdrop-filter: blur(16px);
    box-shadow: var(--shadow-sm);
    /* Ponad plywajacymi kartami (900-1500) — dropdowny menu musza je nakrywac;
       modale i paleta (2000+) zostaja wyzej. */
    z-index: 1900;
}

.brand {
    display: flex;
    align-items: center;
    gap: 12px;
    flex: 0 0 auto;
}

.brand-mark {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    /* Bylo 44x36, gdy w srodku bylo samo "CAD". Teraz niesie logo + nazwe,
       wiec szerokosc musi isc za trescia. */
    padding: 0 10px;
    height: 36px;
    border: 1px solid var(--line-strong);
    border-radius: 8px;
    background: var(--accent-soft);
    color: var(--accent);
    font-size: 14px;
    font-weight: 800;
    letter-spacing: 0.5px;
}

.brand-mark.menu-trigger {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 0 10px;
    height: 36px;
    border: 1px solid var(--line-strong) !important;
    border-radius: 8px;
    background: var(--accent-soft) !important;
    color: var(--accent) !important;
    font-size: 14px;
    font-weight: 800;
    letter-spacing: 0.5px;
    cursor: pointer;
    min-height: 36px !important;
    padding: 0 !important;
}

.brand-mark.menu-trigger:hover,
.menu-dropdown.is-open .brand-mark.menu-trigger {
    background: var(--accent) !important;
    color: #ffffff !important;
    border-color: var(--accent) !important;
}

.navbar-menus {
    display: flex;
    align-items: center;
    gap: 8px;
}

.menu-dropdown {
    position: relative;
}

.menu-trigger {
    background: transparent !important;
    border: 1px solid transparent !important;
    padding: 6px 12px;
    font-size: 13px;
    font-weight: 600;
    color: var(--muted);
    border-radius: 6px;
    transition: all 0.15s ease;
    min-height: 28px !important;
}

.menu-trigger:hover,
.menu-dropdown.is-open .menu-trigger {
    background: var(--hover-bg) !important;
    border-color: var(--glass-border) !important;
    color: var(--text);
}

.menu-content {
    display: none;
    flex-direction: column;
    position: absolute;
    top: calc(100% + 4px);
    right: 0;
    min-width: 220px;
    background: var(--panel-solid);
    backdrop-filter: blur(20px);
    border: 1px solid var(--glass-border);
    border-radius: 8px;
    box-shadow: var(--shadow-lg);
    padding: 6px 0;
    z-index: 1000;
}

.brand-dropdown .menu-content {
    min-width: 280px;
}

.menu-dropdown.is-open .menu-content {
    display: flex;
}

.menu-content button {
    display: flex;
    align-items: center;
    justify-content: space-between;
    width: 100%;
    background: transparent !important;
    border: none !important;
    border-radius: 0 !important;
    padding: 8px 16px;
    font-size: 12px;
    color: var(--text) !important;
    text-align: left;
    min-height: 32px !important;
    cursor: pointer;
}

.menu-content button:hover {
    background: var(--hover-bg) !important;
}

.menu-content button:disabled {
    opacity: 0.4;
    cursor: not-allowed;
}

.menu-content button .icon {
    margin-right: 8px;
    font-size: 14px;
}

.menu-content button .shortcut {
    font-size: 10px;
    color: var(--muted);
    font-weight: normal;
    margin-left: auto;
}

.menu-separator {
    height: 1px;
    background: var(--line);
    margin: 6px 0;
}

.topbar-center {
    display: flex;
    align-items: center;
    gap: 6px;
}

.snap-menu {
    min-width: 200px;
}

/* Bez !important: paleta na dole nadpisuje te reguly swoim stanem wl./wyl.
   (.constraint-palette .snap-menu-item.is-active) — z !important przycisk
   po kliknieciu wygladal identycznie i "nic sie nie dzialo". */
.snap-menu-item {
    display: flex;
    align-items: center;
    gap: 10px;
    justify-content: flex-start;
    width: 100%;
    background: transparent;
    border: none;
    border-radius: 0;
    padding: 8px 16px;
    font-size: 12px;
    color: var(--muted);
    text-align: left;
    min-height: 32px;
    cursor: pointer;
    white-space: nowrap;
}

.snap-menu-item svg {
    flex: 0 0 auto;
    color: var(--muted);
}

.snap-menu-item span:first-of-type {
    flex: 1 1 auto;
}

.snap-menu-item .menu-check {
    flex: 0 0 auto;
    color: var(--accent);
    font-weight: 700;
    opacity: 0;
}

.snap-menu-item:hover {
    background: var(--hover-bg);
}

.snap-menu-item.is-active {
    color: var(--text);
}

.snap-menu-item.is-active svg {
    color: var(--accent);
}

.snap-menu-item.is-active .menu-check {
    opacity: 1;
}

/* ── Etykiety i zwijane podsekcje menu CAD ── */
.menu-section-label {
    padding: 6px 16px 2px;
    color: #8b9bb4;
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    user-select: none;
}

.menu-subtoggle {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 8px 16px;
    font-size: 12px;
    color: var(--text);
    cursor: pointer;
    user-select: none;
}

.menu-subtoggle:hover {
    background: var(--hover-bg);
}
/* Pozycje podmenu (Importuj…, Eksportuj…) wciete pod swoim naglowkiem. */
.menu-submenu > button { padding-left: 32px; }

/* ── Ribbon narzędzi pod górnym paskiem ── */
/* Narzedzia w glownym pasku — kompaktowe, same ikony (podpisy w title). */
.topbar-tools {
    display: flex;
    align-items: center;
    gap: 6px;
    flex: 1;
    min-width: 0;
    overflow-x: auto;
}

.topbar-tools .tool-grid {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: max-content;
    grid-template-columns: none;
    gap: 4px;
}

.topbar-tools .tool-btn {
    width: 38px;
    height: 38px;
}

.topbar-tools .tool-btn span {
    display: none;
}

/* Segmentowy przełącznik trybu pracy: Szkic / Bryła / Zespół */

/* Kontekstowy chip parametru (mm) — pojawia się tylko dla fillet/chamfer */
.tool-options-chip {
    position: absolute;
    top: 12px;
    left: 50%;
    transform: translateX(-50%);
    z-index: 95;
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 12px;
    background: var(--panel);
    border: 1px solid var(--accent);
    border-radius: 8px;
    box-shadow: var(--shadow-md);
    white-space: nowrap;
}

.tool-options-chip #param-label {
    font-size: 11px;
    color: var(--muted);
}

.joint-kind-row {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 12px;
    cursor: pointer;
    white-space: nowrap;
}

.joint-kind-row input {
    accent-color: var(--accent);
    cursor: pointer;
}

.tool-options-chip #param-input {
    width: 80px;
    padding: 4px 6px;
    border: 1px solid var(--line);
    border-radius: 4px;
    background: var(--bg-card);
    color: var(--text);
    font-size: 12px;
}

.ribbon-finish {
    border: none;
    border-radius: 6px;
    padding: 8px 12px;
    font-weight: 700;
    font-size: 12px;
    color: #ffffff;
    cursor: pointer;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    white-space: nowrap;
}

/* ── Wstazka ─────────────────────────────────────────────────────────
   Grupy z etykieta nad kaflami, kafel 64x56, skrot w narozniku, pionowa
   linia miedzy grupami. Bez backdrop-filter — podwojny blur (topbar +
   wstazka) tworzy osobne konteksty stackingu i potrafi odciac popover
   mimo poprawnego z-index. */
/* Wiersz gridu mieszczacy wstazke i pasek aktywnego szkicu. */
.ribbon-row {
    display: flex;
    align-items: stretch;
    min-width: 0;
    background: var(--panel-solid);
    border-bottom: 1px solid var(--line);
}

.ribbon-row > .ribbon { flex: 1; min-width: 0; border-bottom: none; }

/* Grupa akcji na prawym koncu wstazki.

   Kazda plansza robocza konczy sie tym samym: etykieta kontekstu i akcja
   glowna w kolorze akcentu — AKTYWNY SZKIC + Zakoncz szkic, WYNIK + Eksport,
   WYNIK + Zapisz G-code. Uklad powtarza grupe wstazki (etykieta nad trescia),
   zeby oko czytalo ja jako ostatnia grupe, a nie jako obcy pasek. */
.ribbon-actions {
    display: flex;
    flex-direction: column;
    gap: 4px;
    justify-content: center;
    padding: 6px 12px 8px;
    border-left: 1px solid var(--line);
}

.ribbon-actions-label {
    font-size: 9px;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--muted);
    white-space: nowrap;
    padding-left: 2px;
}

.ribbon-actions-row {
    display: flex;
    align-items: center;
    gap: 6px;
}

.ribbon-action {
    padding: 7px 14px;
    border: 1px solid var(--line-strong);
    border-radius: 6px;
    background: none;
    color: var(--text);
    font-size: 11px;
    font-weight: 600;
    min-height: auto;
    white-space: nowrap;
    cursor: pointer;
}
.ribbon-action:hover:not(:disabled) { background: var(--hover-bg); }
.ribbon-action:disabled { opacity: 0.4; cursor: default; }

.ribbon-action--primary {
    background: var(--accent);
    border-color: var(--accent);
    color: var(--accent-ink);
}
.ribbon-action--primary:hover:not(:disabled) { background: var(--accent-dark); border-color: var(--accent-dark); }
/* Glowny przycisk ma wlasny stan wcisniecia — bazowy rozjasnialby go do
   --accent-soft, czyli odwracal hierarchie w polowie klikniecia. */
.ribbon-action--primary:active:not(:disabled) {
    background: var(--accent-dark);
    border-color: var(--accent-dark);
    color: var(--accent-ink);
}

.ribbon {
    display: flex;
    align-items: flex-start;
    gap: 0;
    /* Wiersz ma z projektu 122 px; grupa (etykieta 12 + kafle 56 + "Wiecej" 18
       plus dwie przerwy) zajmuje 94, wiec na oddech zostaje 14 + 14. */
    padding: 12px 10px 14px;
    background: var(--panel-solid);
    border-bottom: 1px solid var(--line);
    /* Nizej niz topbar (dropdowny), wyzej niz plywajace karty. */
    z-index: 1800;
    /* Wstazka nie miesci sie w waskim oknie — PRZEWIJA SIE poziomo, zamiast
       rozpychac strone. Popover "Wiecej" siedzi w body (position: fixed),
       wiec przyciecie mu nie szkodzi. */
    overflow-x: auto;
    overflow-y: hidden;
    scrollbar-width: thin;
}

.ribbon-group {
    display: flex;
    flex-direction: column;
    flex-shrink: 0; /* kafle maja stala szerokosc; grupa sie nie sciska, tylko przewija */
    gap: 4px;
    padding: 0 10px;
    border-right: 1px solid var(--line);
}

.ribbon-group:last-child { border-right: none; }

/* Katalog narzedzi trzyma sie prawej krawedzi. */
.ribbon-group--end {
    margin-left: auto;
    border-right: none;
    border-left: 1px solid var(--line);
}

.ribbon-group-label {
    font-size: 9px;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--muted);
    padding-left: 2px;
}

.ribbon-tiles {
    display: flex;
    gap: 4px;
}

.ribbon-tile {
    position: relative;
    width: 64px;
    height: 56px;
    /* button { min-height: 36px } jest globalne — bez tego kafel urosnie. */
    min-height: 56px;
    padding: 6px 4px 4px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 4px;
    background: transparent;
    border: 1px solid transparent;
    border-radius: 8px;
    color: var(--text);
    text-align: center;
    transition: background 120ms ease, border-color 120ms ease;
}

.ribbon-tile svg {
    width: 20px;
    height: 20px;
}

.ribbon-tile-label {
    font-size: 10px;
    font-weight: 500;
    line-height: 1.1;
    color: var(--muted);
    max-width: 60px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.ribbon-tile-key {
    position: absolute;
    top: 3px;
    right: 5px;
    font-family: var(--font-mono, ui-monospace, monospace);
    font-size: 9px;
    line-height: 1;
    color: var(--muted);
    opacity: 0.7;
}

.ribbon-tile:hover:not(:disabled) {
    background: var(--hover-bg, rgba(255, 255, 255, 0.06));
    border-color: var(--hover-border, rgba(255, 255, 255, 0.12));
}

.ribbon-tile.is-active {
    background: var(--accent-soft);
    border-color: var(--accent);
}

.ribbon-tile.is-active .ribbon-tile-label,
.ribbon-tile.is-active .ribbon-tile-key {
    color: var(--accent);
}

/* Narzedzie poza swoim kontekstem zostaje WIDOCZNE, ale wygaszone — grupy
   sa widoczne naraz, wiec chowanie kafli przestawialoby caly uklad. */
.ribbon-tile:disabled,
.ribbon-tile.is-disabled {
    opacity: 0.32;
    cursor: not-allowed;
}

.ribbon-more {
    width: 100%;
    min-height: 18px;
    padding: 2px 6px;
    border: none;
    border-radius: 5px;
    background: var(--soft);
    color: var(--muted);
    font-size: 9px;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    cursor: pointer;
}

/* Kafel-menu: grupa schowana w innej (bryly podstawowe w "Bryle"). Strzalka
   siedzi tam, gdzie zwykly kafel ma skrot. */
.ribbon-tile-caret {
    position: absolute;
    top: 2px;
    right: 5px;
    font-size: 10px;
    line-height: 1;
    color: var(--muted);
    opacity: 0.7;
}
.ribbon-tile.is-active .ribbon-tile-caret { color: var(--accent); }

.ribbon-popover.ribbon-menu {
    width: 224px;
    padding: 6px;
}
.ribbon-popover.ribbon-menu .ribbon-pop-section { margin: 4px 8px 6px; }

.ribbon-menu-row {
    display: flex;
    align-items: center;
    gap: 8px;
    width: 100%;
    min-height: auto;
    padding: 5px 8px;
    border: none;
    border-radius: 5px;
    background: none;
    color: var(--text);
    font-size: 12px;
    text-align: left;
    cursor: pointer;
}
.ribbon-menu-row svg { width: 18px; height: 18px; flex-shrink: 0; color: var(--muted); }
.ribbon-menu-row .ribbon-pop-name { flex: 1; }
.ribbon-menu-row:hover:not(:disabled) { background: var(--hover-bg, rgba(255, 255, 255, 0.06)); }
.ribbon-menu-row:hover:not(:disabled) svg { color: var(--text); }
.ribbon-menu-row:disabled { opacity: 0.35; cursor: not-allowed; }

/* Wejscie do personalizacji grupy, ktora nie ma nic w ukryciu. Stonowane,
   zeby nie krzyczalo obok "WIECEJ · n", ale obecne — inaczej grupa
   z kompletem przypietych kafli wyglada na niekonfigurowalna. */
.ribbon-more--customize {
    background: transparent;
    opacity: 0.5;
}

.ribbon-more--customize:hover {
    background: var(--soft);
    opacity: 1;
}

.ribbon-more:hover {
    background: var(--hover-bg, rgba(255, 255, 255, 0.08));
    color: var(--text);
}

/* Zakladka "Wiezy": [Dodaj wiez] + (po aktywacji) hint + przyciski wiezow,
   wszystko w jednym kompaktowym wierszu — panel nie puchnie w pionie. */
.constraint-bar {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    margin-bottom: 4px;
}

#constraint-section {
    display: flex;
    align-items: center;
    gap: 8px;
    overflow-x: auto;
    min-width: 0;
}

#constraint-section .constraint-grid {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: max-content;
    gap: 3px;
}

/* Paleta wiezow ma WLASNA klase, nie .tool-btn. Wczesniej dzielila ja
   z paskiem narzedzi, wiec kazda zmiana wygladu kafla (rozmiar, ramka,
   podswietlenie) wyciekala do dolnego panelu — komponentu, ktory z paskiem
   nie ma nic wspolnego. */
.constraint-btn {
    width: 28px;
    height: 28px;
    min-height: 28px;
    padding: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--soft);
    border: 1px solid var(--glass-border);
    border-radius: 6px;
    color: var(--text);
    text-align: center;
    transition: all 150ms cubic-bezier(0.4, 0, 0.2, 1);
}

.constraint-btn:hover:not(:disabled) {
    background: var(--hover-bg);
    border-color: var(--hover-border);
}

/* ── Pływające karty (Parametry, Właściwości, Elementy) ── */
.floating-card {
    position: fixed;
    width: 260px;
    max-height: 70vh;
    display: flex;
    flex-direction: column;
    background: var(--panel-solid);
    border: 1px solid var(--glass-border);
    border-radius: 10px;
    box-shadow: var(--shadow-md);
    z-index: 1200;
}

.floating-card-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 8px 12px;
    color: #8b9bb4;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    cursor: move;
    user-select: none;
    border-bottom: 1px solid var(--line);
}

.floating-card-header button {
    background: none !important;
    border: none !important;
    color: var(--muted);
    cursor: pointer;
    font-size: 13px;
    line-height: 1;
    padding: 0 2px;
    min-height: auto !important;
}

.floating-card-header button:hover {
    color: var(--text);
}

.floating-card-body {
    overflow-y: auto;
    padding: 8px 10px;
}

.floating-card.is-collapsed .floating-card-body {
    display: none;
}

.floating-card.is-collapsed .floating-card-header {
    border-bottom: none;
}

/* ── Panel zadokowany do krawedzi ──
   Rozny od plywajacego trzema rzeczami: siega od wstazki do dolu ekranu,
   traci zaokraglenie i obramowanie od strony krawedzi (inaczej wyglada na
   przyklejony tasma, a nie wpuszczony w bok okna) i przepuszcza scene.
   Wysokosc ustawia JS — kolumna dzieli sie miedzy panele przy tej samej
   krawedzi. */
.floating-card.is-docked {
    max-height: none;
    background: transparent;
    border-color: transparent;
    box-shadow: none;
    transition: background 0.14s ease-out, border-color 0.14s ease-out;
}

/* Tlo znika calkiem — zostaja napisy, kontrolki i belka tytulowa, wiec
   panel przestaje byc plyta polozona na modelu (drzewko z Fusion). Sam
   naglowek krycie zachowuje, bo to jedyny uchwyt do przeciagania:
   przezroczysty nie mialby gdzie sie zaczynac ani konczyc. */
.floating-card.is-docked .floating-card-header {
    background: var(--panel-docked);
    backdrop-filter: blur(8px);
    border-radius: inherit;
}

/* Napisy leza wprost na scenie, wiec dostaja obwodke w kolorze panelu —
   bez niej ciemny tekst gubi sie na cieniu, a jasny na jasnym tle. */
.floating-card.is-docked:not(:hover):not(:focus-within) .floating-card-body {
    text-shadow: 0 0 3px var(--panel-solid), 0 0 6px var(--panel-solid);
}

.floating-card.is-docked:hover,
.floating-card.is-docked:focus-within {
    background: var(--panel-solid);
    border-color: var(--glass-border);
}

.floating-card.is-docked:hover .floating-card-header,
.floating-card.is-docked:focus-within .floating-card-header {
    background: transparent;
    backdrop-filter: none;
}

.floating-card.is-docked.dock-lewo {
    border-left: none;
    border-radius: 0 10px 10px 0;
}

.floating-card.is-docked.dock-prawo {
    border-right: none;
    border-radius: 10px 0 0 10px;
}

/* Zwiniety panel w doku nie ma czym wypelnic kolumny. */
.floating-card.is-docked.is-collapsed {
    height: auto !important;
}

/* Podswietlenie miejsca, w ktore panel spadnie po puszczeniu. */
.dock-hint {
    position: fixed;
    display: none;
    z-index: 1150;
    background: var(--accent);
    opacity: 0.16;
    border-radius: 10px;
    pointer-events: none;
}

#elements-browser {
    z-index: 900;
}

/* GESTOSC DRZEWA W JEDNYM MIEJSCU. Wiersze buduje kilkanascie funkcji
   w ui.js, kazda wlasnym stylem w atrybucie — a styl w atrybucie wygrywa
   z arkuszem, wiec samego "zmniejsz w CSS" nie da sie zrobic. Wiersze
   czytaja wiec te zmienne, a tutaj stoi jedyny komplet liczb.

   Zespol z Fusiona potrafi miec kilkadziesiat czesci: przy poprzednich
   odstepach na ekran wchodzilo ich dziesiec. */
.elements-list {
    --tree-row-pad: 2px 6px;
    --tree-row-font: 11px;
    --tree-icon: 12px;
    --tree-icon-gap: 6px;
    --tree-gap: 1px;
    --tree-sec-gap: 8px;
    --tree-head-font: 10px;
    --tree-head-gap: 3px;
    --tree-indent: 16px;
    --tree-btn: 18px;
}

/* Globalne `button { min-height: 36px }` jest dobre dla przyciskow, w ktore
   sie celuje palcem, ale w drzewie trzyma kazdy wiersz na 36 px niezaleznie
   od czcionki i odstepow — to ono, a nie tekst, decydowalo o wysokosci.
   Celem klikniecia jest tu caly wiersz, ikonki sa dodatkiem. */
.elements-list button {
    min-height: var(--tree-btn, 18px);
    padding: 0 2px;
    line-height: 1;
}

#params-section {
    z-index: 1400;
}

/* Siatka zamiast kolumny flex: panel modulu (CAM) staje OBOK kanwy, a nie
   pod nia. Przy ukrytym panelu kolumna `auto` ma szerokosc zero, wiec uklad
   bez CAM wyglada dokladnie tak jak wczesniej. */
.workspace {
    display: grid;
    /* Trzy kolumny: lista operacji, plotno, ustawienia. Ukryty panel ma
       szerokosc zero, wiec uklad bez CAM wyglada tak jak wczesniej. */
    grid-template-columns: auto minmax(0, 1fr) auto;
    grid-template-rows: minmax(0, 1fr) auto;
    min-height: 0;
    background: var(--work-bg);
}
.workspace > .ops-panel { grid-column: 1; grid-row: 1; }
.workspace > .canvas-area { grid-column: 2; grid-row: 1; }
.workspace > .module-panel { grid-column: 3; grid-row: 1; }
.workspace > .panel-bottom { grid-column: 1 / -1; grid-row: 2; }

/* Lista operacji po LEWEJ stronie plotna.

   Plansza 3 rozdziela dwie rzeczy, ktore u nas siedzialy w jednym panelu:
   KOLEJNOSC (co po czym, ile trwa) i USTAWIENIA (czym, jak gleboko).
   Pierwsza czyta sie jak plan roboty i musi byc widoczna caly czas; druga
   dotyczy jednej operacji i zmienia sie z zaznaczeniem. */
.ops-panel {
    width: 232px;
    display: flex;
    flex-direction: column;
    min-height: 0;
    overflow-y: auto;
    padding: 12px;
    background: var(--panel-solid);
    border-right: 1px solid var(--line);
}

.ops-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    margin-bottom: 8px;
}
.ops-title {
    font-size: 9px;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--muted);
}
.ops-count {
    font-family: var(--font-mono);
    font-size: 11px;
    color: var(--muted);
}

.ops-list { display: flex; flex-direction: column; gap: 4px; }

.ops-row {
    display: grid;
    grid-template-columns: 18px 1fr auto;
    align-items: center;
    gap: 8px;
    padding: 7px 8px;
    border: 1px solid var(--line);
    border-radius: 6px;
    background: var(--panel);
    cursor: pointer;
    text-align: left;
    min-height: auto;
    width: 100%;
    color: var(--text);
}
.ops-row:hover { background: var(--hover-bg); }
.ops-row.is-active {
    border-color: var(--accent);
    background: var(--accent-soft);
}
.ops-row.is-bad { border-color: var(--danger); }

.ops-index {
    font-family: var(--font-mono);
    font-size: 10px;
    color: var(--muted);
}
.ops-name { font-size: 12px; font-weight: 600; }
.ops-time {
    font-family: var(--font-mono);
    font-size: 11px;
    color: var(--muted);
}

.ops-total {
    display: flex;
    justify-content: space-between;
    margin-top: 8px;
    padding-top: 8px;
    border-top: 1px solid var(--line);
    font-size: 11px;
    font-weight: 700;
}
.ops-total-value { font-family: var(--font-mono); }

.ops-order {
    display: flex;
    gap: 4px;
    margin-top: 8px;
}
.ops-order-btn {
    flex: 1;
    padding: 4px;
    border: 1px solid var(--line);
    border-radius: 5px;
    background: none;
    color: var(--muted);
    font-size: 11px;
    min-height: auto;
    cursor: pointer;
}
.ops-order-btn:hover:not(:disabled) { background: var(--hover-bg); color: var(--text); }
.ops-order-btn:disabled { opacity: 0.35; cursor: default; }

.ops-empty {
    font-size: 11px;
    color: var(--muted);
    line-height: 1.5;
}

.panel-bottom {
    flex: 0 0 auto;
    display: flex;
    flex-direction: column;
    min-height: 0;
    max-height: 130px;
    border-top: 1px solid var(--line-strong);
    /* Panel musi byc nieprzezroczysty — inaczej pole robocze przebija przez
       pasek zakladek i wyglada jakby pasek byl wyciety. */
    background: var(--panel-solid);
}

/* Zakladki dolnego panelu mowia tym samym jezykiem, co zakladki modulow
   w naglowku: pigulka z obramowaniem, akcent na aktywnej. Wczesniej udawaly
   zakladki przegladarki (zaokraglenie tylko u gory, obcieta dolna krawedz),
   czego nie robi zaden inny element tego interfejsu. */
/* Zwiniety panel to sam rzad zakladek — pelni role uchwytu. */
.panel-bottom.is-collapsed .panel-bottom-body { display: none; }
.panel-bottom.is-collapsed { max-height: none; }

.panel-bottom-tabs {
    display: flex;
    gap: 2px;
    padding: 6px 10px 2px;
    flex-shrink: 0;
}

.panel-tab-btn {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    border: 1px solid transparent;
    border-radius: 7px;
    background: none;
    color: var(--muted);
    font-size: 12px;
    font-weight: 600;
    padding: 5px 10px;
    min-height: auto;
    cursor: pointer;
    transition: background 0.12s ease, color 0.12s ease, border-color 0.12s ease;
}

/* IKONA ZE SPRITE'U MA DOMYSLNIE OBRYS, NIE WYPELNIENIE.
   Regula byla dotad zapisana osobno przy kazdym miejscu uzycia
   (.panel-tab-btn, .history-add-btn, .viewport-btn). Kazdy nowy przycisk
   z ta sama ikona zaczynal wiec od czarnej plamy — SVG bez `fill: none`
   wypelnia sciezki na czarno. Regula bazowa zamyka ten rodzaj bledu raz. */
.tab-ico {
    width: 15px;
    height: 15px;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.7;
    stroke-linecap: round;
    stroke-linejoin: round;
    flex-shrink: 0;
}

.panel-tab-btn .tab-ico {
    width: 15px;
    height: 15px;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.7;
    stroke-linecap: round;
    stroke-linejoin: round;
    flex-shrink: 0;
}

.panel-tab-btn:hover { color: var(--text); background: var(--soft); }

.panel-tab-btn.is-active {
    background: var(--accent-soft);
    border-color: var(--accent);
    color: var(--accent);
}

/* Znacznik kamienia milowego stoi obok osi czasu, wiec ma byc kwadratowy
   i cichy — to akcja pomocnicza, nie druga zakladka. */
.history-add-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    min-height: 0;
    padding: 0;
    border: 1px solid var(--line);
    border-radius: 7px;
    background: var(--panel-solid);
    color: var(--muted);
    cursor: pointer;
    transition: color 0.12s ease, border-color 0.12s ease;
}

.history-add-btn .tab-ico { width: 15px; height: 15px; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
.history-add-btn:hover { color: var(--accent); border-color: var(--accent); }

.panel-bottom-body {
    flex: 0 1 auto;
    min-height: 0;
    max-height: 90px;
    overflow: auto;
    padding: 4px 8px;
    border-top: 1px solid var(--line);
}

.panel-tab-content {
    display: none;
}

.panel-tab-content.is-active {
    display: block;
}

.panel-tab-toolbar {
    display: flex;
    justify-content: flex-end;
    margin-bottom: 4px;
}

.snap-menu-inline {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}

.snap-menu-inline .snap-menu-item {
    display: flex;
    align-items: center;
    gap: 6px;
    width: auto;
}

/* Historia — pozioma, przewijalna oś czasu; jednowierszowy cienki pasek,
   milestone'y wyroznione mala ikona (nie duzy badge). */
.history-timeline-row {
    display: flex;
    align-items: center;
    gap: 6px;
}

.history-timeline {
    display: flex;
    align-items: center;
    gap: 2px;
    overflow-x: auto;
    padding: 3px 2px;
    min-height: 28px;
    flex: 1;
    min-width: 0;
}

.history-branch-row {
    display: flex;
    align-items: center;
    gap: 2px;
}

.history-node {
    flex-shrink: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2px;
    background: none;
    border: none;
    color: var(--muted);
    cursor: pointer;
    padding: 2px;
    border-radius: 6px;
}

.history-node:hover {
    background: var(--bg-card);
}

.history-node-dot {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: var(--muted);
}

.history-node-dot.has-icon {
    width: 18px;
    height: 18px;
    border-radius: 4px;
    background: rgba(255, 255, 255, 0.03);
    border: 1px solid var(--glass-border);
    color: var(--muted);
    display: flex;
    align-items: center;
    justify-content: center;
}
.history-node-dot.has-icon svg {
    width: 13px;
    height: 13px;
}
.history-node.is-inactive {
    opacity: 0.35;
    filter: grayscale(1);
}
.history-node.is-inactive:hover {
    opacity: 0.75;
}
.history-node.is-milestone .history-node-dot {
    width: 18px;
    height: 18px;
    border-radius: 4px;
    background: rgba(255, 255, 255, 0.03);
    border: 1px solid var(--glass-border);
    color: var(--accent);
    display: flex;
    align-items: center;
    justify-content: center;
}

.history-node.is-milestone .history-node-dot svg {
    width: 12px;
    height: 12px;
}

.history-node.is-current .history-node-dot {
    outline: 2px solid var(--accent);
    outline-offset: 1px;
    color: var(--accent);
}

.history-node-label {
    font-size: 9px;
    white-space: nowrap;
    max-width: 70px;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Laczniki miedzy krokami skurczone do kreski 3 px — ikony stoja obok
   siebie, ale ciaglosc osi dalej widac. */
.history-connector {
    flex-shrink: 0;
    width: 3px;
    height: 2px;
    background: var(--line);
}

.constraints-list {
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.constraint-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    padding: 4px 8px;
    border-radius: 6px;
    font-size: 12px;
    color: var(--text);
    cursor: pointer;
}

.constraint-row:hover {
    background: var(--bg-card);
}

.constraint-row.is-selected {
    background: var(--bg-card);
    outline: 1px solid var(--accent);
}

.constraint-row-delete {
    background: none;
    border: none;
    color: var(--muted);
    cursor: pointer;
    font-size: 12px;
}

.constraints-empty,
.history-empty {
    color: var(--muted);
    font-size: 12px;
    padding: 8px 4px;
}

.button-row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 10px;
}

.button-row button,
.panel-bottom button {
    font-size: 13px;
}

.tool-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 6px;
}

.tool-btn {
    height: 40px;
    padding: 4px 3px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 2px;
    background: var(--soft);
    border: 1px solid var(--glass-border);
    border-radius: 6px;
    color: var(--text);
    text-align: center;
    transition: all 150ms cubic-bezier(0.4, 0, 0.2, 1);
}

.tool-btn svg {
    width: 14px;
    height: 14px;
}

.tool-btn span {
    display: block;
    color: var(--muted);
    font-size: 9px;
    font-weight: 500;
    line-height: 1.1;
}

.tool-btn:hover:not(.is-active) {
    background: var(--hover-bg);
    border-color: var(--hover-border);
}

.tool-btn.is-active {
    border-color: var(--accent);
    background: var(--accent);
    color: #ffffff;
    box-shadow: 0 0 20px rgba(59, 130, 246, 0.45);
}

.tool-btn.is-active span {
    color: var(--text);
}

.field {
    display: grid;
    gap: 8px;
    color: var(--muted);
    font-size: 12px;
}

.field input {
    width: 100%;
    height: 38px;
    border: 1px solid var(--glass-border);
    border-radius: 8px;
    padding: 0 12px;
    background: rgba(0, 0, 0, 0.2);
    color: var(--text);
    outline: none;
    transition: all 150ms ease;
}

.field input:focus {
    border-color: var(--accent);
    background: rgba(0, 0, 0, 0.35);
    box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.25);
}

.check {
    display: flex;
    align-items: center;
    gap: 10px;
    min-height: 32px;
    color: #d1d5db;
    font-size: 13px;
    cursor: pointer;
}

.check input {
    width: 16px;
    height: 16px;
    accent-color: var(--accent);
    cursor: pointer;
    border-radius: 4px;
    border: 1px solid var(--glass-border);
    background: rgba(0, 0, 0, 0.2);
}

.danger {
    border-color: rgba(239, 68, 68, 0.3);
    background: var(--danger-soft);
    color: #fca5a5;
}

.danger:hover:not(:disabled) {
    border-color: var(--danger);
    background: rgba(239, 68, 68, 0.25);
    box-shadow: 0 4px 12px rgba(239, 68, 68, 0.15);
}

.canvas-area {
    flex: 1 1 auto;
    position: relative;
    min-width: 0;
    min-height: 0;
    padding: 0;
    background: var(--work-bg);
}

#cad-canvas {
    display: block;
    width: 100%;
    height: 100%;
    background: var(--canvas);
}

#three-container {
    width: 100%;
    height: 100%;
    background: var(--canvas);
    overflow: hidden;
}

.floating-hint {
    position: absolute;
    left: 36px;
    /* Nad paleta wiezow, nie na jej wysokosci — paleta stoi wysrodkowana
       na 40 px i przy waskim oknie siegalaby az tutaj. */
    bottom: 92px;
    max-width: min(620px, calc(100% - 72px));
    padding: 10px 16px;
    border: 1px solid var(--glass-border);
    border-radius: 8px;
    /* Bylo tu na sztywno rgba(15,23,42,.85) — czarna plama na jasnym
       motywie "papier", niezaleznie od tego, co uzytkownik wybral. */
    background: var(--panel-docked);
    backdrop-filter: blur(8px);
    color: var(--text);
    font-size: 12px;
    font-weight: 500;
    box-shadow: var(--shadow-md);
    pointer-events: none;
    line-height: 1.4;
    transition: opacity 0.45s ease-out, transform 0.2s ease;
}

/* Podpowiedz mowi, co robi WLASNIE WYBRANE narzedzie — po kilku sekundach
   jest juz tylko przeszkoda na plotnie. Wraca sama przy kazdej zmianie
   narzedzia, wiec nie trzeba jej szukac w ustawieniach. */
.floating-hint.is-faded {
    opacity: 0;
}

.properties-list {
    display: grid;
    grid-template-columns: minmax(90px, 1fr) minmax(100px, 1.2fr);
    gap: 8px 12px;
    margin: 0;
    font-size: 13px;
    line-height: 1.4;
}

.properties-list dt {
    color: var(--muted);
    font-weight: 500;
}

.properties-list dd {
    margin: 0;
    color: #f3f4f6;
    font-weight: 600;
    overflow-wrap: anywhere;
}

/* Waskie okno: naglowek zostaje JEDNYM wierszem (dawniej lamal sie w kolumne
   i zjadal pol ekranu), tytul dokumentu sie skraca, a chip parametru traci
   etykiete. */
.topbar > * { min-width: 0; }
.doc-title-wrap { min-width: 0; }
.doc-title { max-width: 32vw; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
@media (max-width: 900px) {
    .topbar { gap: 6px; }
    .brand-name { display: none; }
    #param-label { display: none; }
}

/* Command Palette styles */
.palette-overlay {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: rgba(7, 9, 14, 0.4);
    backdrop-filter: blur(4px);
    z-index: 9999;
    display: flex;
    justify-content: center;
    align-items: flex-start;
    padding-top: 15vh;
}

.palette-window {
    width: 100%;
    max-width: 600px;
    background: var(--panel-solid);
    border: 1px solid var(--glass-border);
    border-radius: 12px;
    box-shadow: 0 20px 50px rgba(0, 0, 0, 0.5);
    overflow: hidden;
    display: flex;
    flex-direction: column;
}

.palette-header {
    padding: 16px;
    border-bottom: 1px solid var(--line);
}

#palette-search {
    width: 100%;
    border: none;
    background: transparent;
    color: var(--text);
    font-size: 16px;
    font-family: inherit;
    outline: none;
}

#palette-search::placeholder {
    color: var(--muted);
}

.palette-results {
    max-height: 300px;
    overflow-y: auto;
    padding: 8px 0;
}

.palette-item {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 10px 18px;
    cursor: pointer;
    font-size: 14px;
    color: var(--text);
    transition: background 0.15s ease;
}

.palette-item.is-selected {
    background: var(--accent-soft);
    color: var(--accent);
}

.palette-shortcut {
    font-size: 11px;
    background: var(--soft);
    border: 1px solid var(--glass-border);
    padding: 2px 6px;
    border-radius: 4px;
    color: var(--muted);
    font-weight: bold;
}

.palette-item.is-selected .palette-shortcut {
    color: var(--accent);
    border-color: var(--accent);
}

.palette-footer {
    display: flex;
    gap: 16px;
    padding: 10px 18px;
    background: rgba(0, 0, 0, 0.2);
    border-top: 1px solid var(--line);
    font-size: 11px;
    color: var(--muted);
}

.palette-footer span {
    display: flex;
    align-items: center;
    gap: 4px;
}

.operation-mode-panel {
    /* Plywajaca, przeciagalna karta nad widokiem 3D — zamiast stalego bloku
       w lewym pasku. Niemodalna: scena pozostaje klikalna (wybor profilu/osi).
       Pozycja (left/top) ustawiana inline przez logike drag w app.js. */
    display: flex;
    flex-direction: column;
    gap: 12px;
    padding: 16px;
    background: var(--bg-card);
    border: 1px solid #f59e0b;
    border-radius: 8px;
    text-align: center;
    position: fixed;
    left: 300px;
    top: 140px;
    width: 240px;
    z-index: 1500;
    box-shadow: 0 12px 32px rgba(0, 0, 0, 0.4);
    /* KARTA NIGDY NIE WYCHODZI POZA EKRAN. Przewija sie SRODEK, a naglowek
       i przyciski zostaja na miejscu — inaczej przy dluzszym panelu
       (prymityw ma wymiary, polozenie, kolor i operacje naraz) "Zastosuj"
       spadal pod krawedz i operacji nie dalo sie zatwierdzic mysza. */
    max-height: calc(100vh - 16px);
    overflow: hidden;
    box-sizing: border-box;
}

/* Srodek karty to jedyna czesc, ktora sie przewija. `min-height: 0` jest
   obowiazkowe: bez niego element flex nie da sie skurczyc ponizej swojej
   zawartosci i max-height karty nic by nie zmienil. */
#op-params {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    overscroll-behavior: contain;
}

/* Sekcje panelu operacji: to, po co uzytkownik przyszedl (wymiary), stoi
   otwarte; polozenie i kolor czekaja zwiniete, bo jedno i drugie da sie
   ustawic wprost w scenie (gizmo, kwadraciki, paleta). */
.op-sekcja {
    border: 1px solid var(--line);
    border-radius: 6px;
    text-align: left;
}
.op-sekcja > summary {
    cursor: pointer;
    font-size: 11px;
    font-weight: 600;
    color: var(--muted);
    padding: 6px 8px;
    list-style: none;
    display: flex;
    align-items: center;
    gap: 6px;
}
.op-sekcja > summary::-webkit-details-marker { display: none; }
.op-sekcja > summary::before {
    content: "\25B8";
    font-size: 9px;
    opacity: 0.7;
}
.op-sekcja[open] > summary::before { content: "\25BE"; }
.op-sekcja > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.op-sekcja-tresc {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 0 8px 8px;
}

/* Kat z suwakiem: ciagniecie jest szybsze niz wpisywanie, ale liczba musi
   zostac — bez niej nie da sie ustawic dokladnie 30 stopni. */
.op-kat {
    display: flex;
    align-items: center;
    gap: 6px;
}
.op-kat input[type="range"] {
    flex: 1 1 auto;
    min-width: 0;
    accent-color: var(--accent);
}
.op-kat input[type="text"] {
    flex: 0 0 52px;
    width: 52px;
    text-align: right;
}

.operation-title {
    font-size: 13px;
    font-weight: 700;
    color: #f59e0b;
    cursor: move;
    user-select: none;
    padding: 2px 0 6px;
    border-bottom: 1px dashed rgba(245, 158, 11, 0.4);
}
.operation-title::before {
    content: "⋮⋮ ";
    opacity: 0.5;
    letter-spacing: -2px;
}

.operation-desc {
    font-size: 11px;
    color: var(--muted);
    line-height: 1.4;
}

.operation-buttons {
    display: flex;
    gap: 8px;
    margin-top: 4px;
}

.operation-buttons button {
    flex: 1;
    font-size: 11px;
    padding: 6px 0;
    min-height: 28px;
    border-radius: 6px;
}

.op-btn-ok {
    background: var(--accent) !important;
    border: none !important;
    color: #ffffff !important;
    font-weight: bold;
}

.op-btn-cancel {
    /* Byl tu wpisany na twardo grafit z bialym tekstem — relikt czasow,
       gdy istnial tylko motyw ciemny. Na papierze wygladal jak obce cialo. */
    background: var(--input-bg) !important;
    border: 1px solid var(--line) !important;
    color: var(--text) !important;
}
.op-btn-cancel.is-active {
    border-color: var(--accent) !important;
    color: var(--accent) !important;
}

/* Panel podkladu: dwie kolumny pol maja sie MIESCIC w karcie. */
#underlay-window { width: 300px; }
#underlay-window .section-field { min-width: 0; }
#underlay-window .section-field input { width: 100%; min-width: 0; box-sizing: border-box; }

/* 3D Viewport controls */
/* Pionowa pigulka nawigacji 3D (uchwyty Obroc/Przesun) przy prawej krawedzi;
   widoki osiowe sa w menu "Widok" i na gizmie XYZ. */
/* Kontrolki widoku to karta w tej samej palecie co panele, a nie szary
   prostokat z emoji. Ikony ze sprite'u, wiec dziedzicza kolor i skaluja sie
   z reszta interfejsu. */
.viewport-controls-3d {
    position: absolute;
    top: 50%;
    right: 12px;
    /* Przy widocznym suwaku warstw klaster przesuwa sie w lewo — inaczej
       obie kontrolki stoja w tej samej kolumnie. */
    transition: right 0.12s ease;
    transform: translateY(-50%);
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2px;
    padding: 3px;
    border: 1px solid var(--line);
    border-radius: 10px;
    background: var(--panel);
    box-shadow: var(--shadow-sm);
    backdrop-filter: blur(8px);
    z-index: 10;
}
/* Wokol gizma osi (96 px, top 8 / right 10): kolumna trzech rzutow po
   lewej, zapis ujecia i zarys pod nim. Bez karty — przezroczyste, zeby nie
   zaslaniac sceny; tlo tylko pod kursorem i na wcisnietym przelaczniku. */
.gizmo-tools { position: absolute; inset: 0; pointer-events: none; z-index: 91; }
.gizmo-tools > * { pointer-events: auto; }
.gizmo-row {
    position: absolute;
    right: 10px;
    width: 96px;
    display: flex;
    justify-content: space-between;
    align-items: center;
}
.gizmo-row-bottom { top: 108px; justify-content: space-around; }
/* Kolumna rzutow po lewej stronie gizma, w jego wysokosci. */
.gizmo-col {
    position: absolute;
    top: 8px;
    right: 112px;
    height: 96px;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    align-items: center;
}
.gizmo-view-btn {
    width: 28px;
    height: 24px;
    min-height: 0; /* globalny button ma min-height, ktory rozpychal rzad na gizmo */
    padding: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 1px solid transparent;
    border-radius: 6px;
    background: transparent;
    color: var(--muted);
    cursor: pointer;
}
.gizmo-view-btn svg { width: 15px; height: 15px; }
.gizmo-view-btn:hover { background: var(--hover-bg); color: var(--text); }
.gizmo-view-btn.is-active {
    background: var(--accent-soft);
    border-color: var(--accent);
    color: var(--accent);
}

/* UWAGA: ta regula miala wczesniej ZDUBLOWANE deklaracje — nowe u gory,
   stare nizej, wiec stare wygrywaly. Wsrod nich siedzialo tlo
   rgba(15, 23, 42, 0.6): granat z ciemnego motywu wpisany na sztywno,
   ktory przezyl cala zmiane palety, bo nikt nie patrzyl na ten element. */

.viewport-controls-3d .viewport-btn {
    width: 34px;
    height: 34px;
    padding: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 15px;
}

.viewport-btn {
    background: transparent !important;
    border: none !important;
    border-radius: 6px !important;
    color: var(--muted);
    font-size: 11px;
    font-weight: 600;
    padding: 6px 10px;
    cursor: pointer;
    transition: all 0.15s ease;
    min-height: auto !important;
}

.viewport-btn:hover {
    background: rgba(255, 255, 255, 0.08) !important;
    color: var(--text);
}

.viewport-btn.drag-btn {
    background: var(--accent-soft) !important;
    color: #60a5fa;
    cursor: grab;
}

.viewport-btn.drag-btn:active {
    cursor: grabbing;
    background: var(--accent) !important;
    color: #ffffff;
}


/* Settings Modal Popup */
.modal-backdrop {
    position: fixed;
    top: 0;
    left: 0;
    width: 100vw;
    height: 100vh;
    background: rgba(0, 0, 0, 0.55);
    backdrop-filter: blur(8px);
    display: flex;
    align-items: center;
    justify-content: center;
    /* Nad arkuszem .exp-sheet (2400). Modal jest z definicji na wierzchu:
       otwiera sie Z arkusza (logowanie, pytanie o nazwe projektu) i blokuje
       reszte interfejsu. Przy 2000 arkusz nakrywal jego prawa krawedz razem
       z przyciskiem potwierdzenia — okno wygladalo na uciete. */
    z-index: 2500;
    animation: fadeIn 0.18s ease-out;
}

.modal-card {
    background: var(--bg-card);
    border: 1px solid var(--glass-border);
    border-radius: 12px;
    box-shadow: var(--shadow-2xl);
    width: 320px;
    max-width: 90%;
    animation: slideUp 0.18s ease-out;
    overflow: hidden;
}

.modal-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 14px 16px;
    border-bottom: 1px solid var(--line);
    background: var(--soft);
}

.modal-header h2 {
    font-size: 15px;
    font-weight: 600;
    margin: 0;
    color: var(--text);
    font-family: 'Outfit', sans-serif;
}

.modal-close-btn {
    background: transparent;
    border: none;
    font-size: 24px;
    color: var(--muted);
    cursor: pointer;
    line-height: 1;
    padding: 2px 6px;
    border-radius: 4px;
    transition: color 0.15s, background 0.15s;
}

.modal-close-btn:hover {
    color: var(--text);
    background: var(--hover-bg);
}

.modal-body {
    padding: 16px;
    display: flex;
    flex-direction: column;
    gap: 16px;
}

.setting-row {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 12px;
    font-size: 12px;
}

.setting-row label {
    color: var(--muted);
}

.setting-row input[type="range"] {
    width: 100px;
    cursor: pointer;
    height: 4px;
    accent-color: var(--accent);
}

.setting-row input[type="number"] {
    width: 60px;
    padding: 4px 6px;
    border: 1px solid var(--line);
    border-radius: 4px;
    background: var(--bg-card);
    color: var(--text);
    text-align: right;
    font-size: 12px;
}

.setting-row input[type="color"] {
    border: none;
    width: 36px;
    height: 22px;
    border-radius: 4px;
    cursor: pointer;
    background: transparent;
    padding: 0;
}

@keyframes fadeIn {
    from { opacity: 0; }
    to { opacity: 1; }
}

@keyframes slideUp {
    from { transform: translateY(12px); }
    to { transform: translateY(0); }
}

/* Floating Viewport Height Input Box */
.viewport-height-input {
    position: absolute;
    transform: translate(-50%, -50%);
    background: var(--bg-card);
    border: 1px solid var(--accent);
    color: var(--text);
    padding: 4px 8px;
    border-radius: 6px;
    font-size: 13px;
    font-weight: bold;
    width: 80px;
    text-align: center;
    box-shadow: var(--shadow-lg);
    outline: none;
    z-index: 10;
    transition: border-color 0.15s, box-shadow 0.15s;
    font-family: 'Outfit', sans-serif;
}

.viewport-height-input:focus {
    box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.4);
    border-color: var(--accent);
}



/* ─────────────── Samouczek pierwszego uruchomienia ─────────────── */
/* Dymek stoi w rogu i NIE przechwytuje klikniec poza wlasnymi przyciskami —
   uzytkownik ma pracowac normalnie, samouczek tylko podpowiada. */
#tutorial-bubble {
    position: fixed;
    left: 18px;
    bottom: 92px;
    z-index: 1500;
    width: 290px;
    padding: 12px 14px;
    border-radius: 10px;
    background: var(--panel-solid);
    border: 1px solid var(--accent);
    box-shadow: var(--shadow-md);
    font-family: var(--font-family);
    color: var(--text);
}
#tutorial-bubble .tutorial-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 8px;
    font-size: 13px;
    margin-bottom: 6px;
}
#tutorial-bubble .tutorial-close {
    background: none;
    border: none;
    color: var(--muted);
    cursor: pointer;
    font-size: 16px;
    line-height: 1;
    padding: 0 2px;
}
#tutorial-bubble .tutorial-close:hover { color: var(--text); }
#tutorial-bubble .tutorial-body {
    font-size: 12px;
    line-height: 1.5;
    color: var(--text);
}
#tutorial-bubble .tutorial-foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-top: 10px;
    font-size: 11px;
    color: var(--muted);
}
#tutorial-bubble .tutorial-skip {
    background: none;
    border: 1px solid var(--line);
    border-radius: 5px;
    color: var(--muted);
    cursor: pointer;
    font-size: 11px;
    padding: 3px 8px;
}
#tutorial-bubble .tutorial-skip:hover { color: var(--text); border-color: var(--line-strong); }

/* Podswietlenie celu biezacego kroku. */
.tutorial-target {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
    border-radius: 6px;
    animation: tutorial-pulse 1.6s ease-in-out infinite;
}
@keyframes tutorial-pulse {
    0%, 100% { box-shadow: 0 0 0 0 rgba(59, 130, 246, 0.45); }
    50%      { box-shadow: 0 0 0 6px rgba(59, 130, 246, 0); }
}
@media (prefers-reduced-motion: reduce) {
    .tutorial-target { animation: none; }
}

/* Przycisk "Wiecej" nie ma ikony — pasek chowa <span>, wiec przywracamy tekst,
   inaczej renderuje sie jako pusty kwadracik. */
.tool-more-btn { min-width: 62px; }
.tool-more-btn span {
    display: inline !important;
    font-size: 10px;
    white-space: nowrap;
    color: var(--muted);
}
.tool-more-btn:hover span { color: var(--text); }

/* ── Pomiary i przekroje (zakladka Plaszczyzna) ────────────────────── */

/* Etykieta pomiaru unosi sie nad kanwa 3D; pozycje ustawia three_view
   rzutujac srodek odcinka na ekran co klatke. */
.measure-label {
    position: absolute;
    transform: translate(-50%, -50%);
    padding: 2px 7px;
    border-radius: 5px;
    background: rgba(245, 158, 11, 0.92);
    color: #1c1917;
    font-family: 'Inter', sans-serif;
    font-size: 11px;
    font-weight: 700;
    white-space: nowrap;
    pointer-events: none;
    user-select: none;
    z-index: 120;
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.35);
}

/* Etykieta wymiaru szkicu w scenie 3D — neutralny dymek jak na kanwie 2D,
   zeby nie mylil sie z bursztynowa etykieta pomiaru. */
.measure-label.dim-label {
    background: var(--panel);
    color: var(--text);
    border: 1px solid var(--line);
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.2);
}

.measure-label.dim-label.selected {
    border-color: #c96a5e;
    color: #c96a5e;
}

.measure-hint {
    font-size: 11px;
    line-height: 1.45;
    color: var(--muted);
    padding: 6px 8px;
    border: 1px dashed var(--line);
    border-radius: 6px;
}

.section-field {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    margin-bottom: 6px;
    font-size: 11px;
    color: var(--muted);
}

.section-field select,
.section-field input {
    flex: 1;
    min-width: 0;
    max-width: 140px;
    background: var(--input-bg, rgba(148, 163, 184, 0.08));
    color: var(--text);
    border: 1px solid var(--line);
    border-radius: 5px;
    padding: 3px 6px;
    font-size: 11px;
}

#section-offset-range {
    width: 100%;
    max-width: none;
    accent-color: var(--accent);
}

/* ── Popover "Więcej": przypinanie kafli do wstążki ──────────────────
   z-index 1850: nad panelem operacji (1500) i kartami (1200-1400),
   pod modalami (2000). */
.ribbon-popover {
    position: fixed;
    z-index: 1850;
    width: 280px;
    max-height: 70vh;
    overflow-y: auto;
    padding: 12px;
    background: var(--panel-solid);
    border: 1px solid var(--line-strong);
    border-radius: 10px;
    box-shadow: var(--shadow-lg);
}

.ribbon-pop-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
}

.ribbon-pop-title {
    font-size: 12px;
    font-weight: 700;
    color: var(--text);
}

.ribbon-pop-close {
    background: none;
    border: none;
    min-height: auto;
    padding: 0 2px;
    color: var(--muted);
    font-size: 13px;
    cursor: pointer;
}
.ribbon-pop-close:hover { color: var(--text); }

.ribbon-pop-hint {
    margin: 2px 0 10px;
    font-size: 10px;
    color: var(--muted);
}

.ribbon-pop-section {
    margin: 10px 0 6px;
    font-size: 9px;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--muted);
}

.ribbon-pop-tiles {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
}

/* Kafel w popoverze pokazuje wyglad docelowy, ale narzedzia NIE uruchamia —
   klika sie go po to, zeby przeciagnac albo zdjac gwiazdka. */
.ribbon-pop-tile {
    cursor: grab;
    border-color: var(--line);
}
.ribbon-pop-tile.is-dragging { opacity: 0.4; }

.ribbon-pop-star {
    position: absolute;
    top: 2px;
    left: 4px;
    font-size: 10px;
    line-height: 1;
    color: var(--accent);
    cursor: pointer;
}

.ribbon-pop-list {
    display: flex;
    flex-direction: column;
    gap: 1px;
}

.ribbon-pop-row {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 5px 6px;
    border-radius: 5px;
}
.ribbon-pop-row:hover { background: var(--hover-bg, rgba(255, 255, 255, 0.05)); }

.ribbon-pop-name {
    flex: 1;
    min-width: 0;
    font-size: 12px;
    color: var(--text);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.ribbon-pop-key {
    font-family: var(--font-mono, ui-monospace, monospace);
    font-size: 10px;
    color: var(--muted);
    background: var(--soft);
    border-radius: 3px;
    padding: 1px 4px;
    min-width: 18px;
    text-align: center;
}

.ribbon-pop-pin {
    background: none;
    border: none;
    min-height: auto;
    padding: 0 2px;
    color: var(--muted);
    font-size: 12px;
    cursor: pointer;
}
.ribbon-pop-pin:hover { color: var(--accent); }

.ribbon-pop-foot {
    display: flex;
    align-items: center;
    gap: 6px;
    margin-top: 12px;
    padding-top: 10px;
    border-top: 1px solid var(--line);
}

.ribbon-pop-draghint {
    flex: 1;
    font-size: 9px;
    line-height: 1.3;
    color: var(--muted);
}

.ribbon-pop-btn {
    padding: 4px 10px;
    border: 1px solid var(--line-strong);
    border-radius: 6px;
    background: none;
    color: var(--text);
    font-size: 11px;
    font-weight: 600;
    min-height: auto;
    cursor: pointer;
}
.ribbon-pop-btn:hover { background: var(--hover-bg, rgba(255, 255, 255, 0.06)); }

.ribbon-pop-btn--primary {
    background: var(--accent);
    border-color: var(--accent);
    color: #ffffff;
}
.ribbon-pop-btn--primary:hover { background: var(--accent); opacity: 0.9; }

/* ── Karta podpowiedzi narzędzia ─────────────────────────────────────
   z-index 1860: nad popoverem "Więcej" (1850), pod modalami (2000). */
.ribbon-tip {
    position: fixed;
    z-index: 1860;
    width: 260px;
    padding: 10px 12px 11px;
    background: var(--panel-solid);
    border: 1px solid var(--line-strong);
    border-radius: 10px;
    box-shadow: var(--shadow-lg);
    pointer-events: none;   /* karta nie moze przechwytywac kliku w kafel */
}

.ribbon-tip-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 8px;
}

.ribbon-tip-title {
    font-size: 13px;
    font-weight: 700;
    color: var(--text);
}

.ribbon-tip-key {
    font-family: var(--font-mono, ui-monospace, monospace);
    font-size: 10px;
    color: var(--muted);
    background: var(--soft);
    border: 1px solid var(--line);
    border-radius: 4px;
    padding: 1px 5px;
}

.ribbon-tip-desc {
    margin-top: 5px;
    font-size: 11.5px;
    line-height: 1.45;
    color: var(--muted);
}

.ribbon-tip-flow {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-top: 10px;
    padding: 8px 10px;
    border: 1px solid var(--line);
    border-radius: 8px;
    background: var(--soft);
    color: var(--text);
}

/* Wejscie rysowane kreskowanym obrysem, wynik pelnym — jak na planszy. */
.ribbon-tip-glyph {
    display: inline-flex;
    padding: 3px;
    border-radius: 6px;
    color: var(--accent);
}
.ribbon-tip-glyph--from {
    border: 1px dashed var(--line-strong);
    color: var(--muted);
}

.ribbon-tip-arrow {
    color: var(--muted);
    font-size: 13px;
}

.ribbon-tip-caption {
    flex: 1;
    text-align: right;
    font-family: var(--font-mono, ui-monospace, monospace);
    font-size: 9.5px;
    line-height: 1.3;
    color: var(--muted);
}

.ribbon-tip-context {
    margin-top: 8px;
    font-size: 10.5px;
    color: var(--accent);
}
.ribbon-tip-context::before { content: "✓ "; }

/* ── Nagłówek: marka, zakładki modułów, tytuł, przełączniki ──────────── */

.brand-mark {
    display: inline-flex !important;
    align-items: center;
    gap: 7px;
}

.brand-name {
    font-family: var(--font-family);
    font-size: 13px;
    font-weight: 700;
    letter-spacing: -0.01em;
    white-space: nowrap;
}

.module-tabs {
    display: flex;
    gap: 2px;
}

.module-tab {
    padding: 6px 12px;
    border: 1px solid transparent;
    border-radius: 7px;
    background: none;
    color: var(--muted);
    font-size: 12px;
    font-weight: 600;
    min-height: auto;
    white-space: nowrap;
    cursor: pointer;
}
.module-tab:hover { background: var(--hover-bg, rgba(255, 255, 255, 0.06)); color: var(--text); }

.module-tab.is-active {
    background: var(--accent-soft);
    border-color: var(--accent);
    color: var(--accent);
}

/* Moduł zapowiedziany, ale jeszcze nieczynny — widoczny, żeby było wiadomo,
   dokąd zmierza program; wygaszony, żeby nie obiecywał działania. */
.module-tab.is-planned { opacity: 0.42; cursor: default; }
.module-tab.is-planned:hover { background: none; color: var(--muted); }

.doc-title-wrap {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-left: 14px;
    padding-left: 14px;
    border-left: 1px solid var(--line);
    min-width: 0;
}

.doc-title {
    padding: 3px 6px;
    border: 1px solid transparent;
    border-radius: 5px;
    background: none;
    color: var(--text);
    font-size: 13px;
    font-weight: 600;
    min-height: auto;
    max-width: 240px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    cursor: text;
}
.doc-title:hover { border-color: var(--line-strong); }
.doc-title.is-untitled { color: var(--muted); font-style: italic; }

.doc-chip {
    padding: 2px 7px;
    border-radius: 4px;
    background: var(--soft);
    border: 1px solid var(--line);
    color: var(--muted);
    font-family: var(--font-mono, ui-monospace, monospace);
    font-size: 10px;
    white-space: nowrap;
}

.seg-switch {
    display: inline-flex;
    padding: 2px;
    gap: 2px;
    background: var(--soft);
    border: 1px solid var(--line);
    border-radius: 7px;
}

.seg-btn {
    padding: 3px 9px;
    border: none;
    border-radius: 5px;
    background: none;
    color: var(--muted);
    font-size: 10.5px;
    font-weight: 600;
    min-height: auto;
    cursor: pointer;
}
.seg-btn:hover { color: var(--text); }
.seg-btn.is-active { background: var(--panel-solid); color: var(--text); box-shadow: var(--shadow-sm); }

/* ── Ekran startowy (plansza 1) ──────────────────────────────────────── */

.start-screen {
    position: absolute;
    inset: 0;
    z-index: 80;
    display: flex;
    align-items: center;
    justify-content: center;
    pointer-events: none;
}

.start-card {
    pointer-events: auto;
    width: min(560px, calc(100% - 48px));
    padding: 26px 28px 20px;
    background: var(--panel-solid);
    border: 1px solid var(--line);
    border-radius: 14px;
    box-shadow: var(--shadow-md);
}

.start-title {
    margin: 0;
    font-size: 20px;
    font-weight: 700;
    letter-spacing: -0.01em;
    color: var(--text);
}

.start-sub {
    margin: 6px 0 18px;
    font-size: 13px;
    line-height: 1.5;
    color: var(--muted);
}

.start-actions {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 8px;
}

.start-action {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 3px;
    padding: 11px 12px;
    border: 1px solid var(--line-strong);
    border-radius: 9px;
    background: none;
    text-align: left;
    min-height: auto;
    cursor: pointer;
}
.start-action:hover { background: var(--hover-bg, rgba(255, 255, 255, 0.05)); }

.start-action-label {
    font-size: 13px;
    font-weight: 600;
    color: var(--text);
}

.start-action-note {
    font-family: var(--font-mono, ui-monospace, monospace);
    font-size: 9.5px;
    color: var(--muted);
}

.start-action--primary {
    background: var(--accent-soft);
    border-color: var(--accent);
}
.start-action--primary .start-action-label { color: var(--accent); }

.start-how { margin-top: 20px; }

.start-how-head {
    font-size: 9px;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--muted);
    margin-bottom: 10px;
}

.start-how-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 12px 18px;
}

.start-how-step {
    display: flex;
    gap: 9px;
    align-items: flex-start;
}

.start-how-num {
    flex: 0 0 auto;
    width: 18px;
    height: 18px;
    display: grid;
    place-items: center;
    border-radius: 50%;
    background: var(--accent-soft);
    color: var(--accent);
    font-family: var(--font-mono, ui-monospace, monospace);
    font-size: 10px;
    font-weight: 600;
}

.start-how-title {
    font-size: 12px;
    font-weight: 600;
    color: var(--text);
}

.start-how-desc {
    margin-top: 1px;
    font-size: 11px;
    line-height: 1.45;
    color: var(--muted);
}

.start-dismiss {
    margin-top: 16px;
    padding: 0;
    background: none;
    border: none;
    min-height: auto;
    color: var(--muted);
    font-size: 11px;
    text-decoration: underline;
    cursor: pointer;
}
.start-dismiss:hover { color: var(--text); }

/* ─────────────── Panel modulu (CAM, Druk 3D) ─────────────── */
/* Siostra <main>, nie jego dziecko: kanwa ma wlasny ResizeObserver, wiec
   zwezenie obszaru rysowania przelicza sie samo. */
.module-panel {
    grid-column: 2;
    grid-row: 1;
    width: 320px;
    overflow-y: auto;
    padding: 14px 16px 20px;
    background: var(--panel);
    border-left: 1px solid var(--line);
    font-size: 13px;
}
.mp-heading { margin: 0 0 12px; font-size: 15px; font-weight: 700; }
.mp-subheading {
    margin: 18px 0 8px; font-size: 11px; font-weight: 700;
    letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted);
}
.mp-section { display: flex; flex-direction: column; gap: 8px; }
.mp-field { display: grid; grid-template-columns: 1fr 130px; align-items: center; gap: 8px; }
.mp-label { color: var(--muted); font-size: 12px; }
.mp-input {
    width: 100%; padding: 5px 7px; font-size: 12px;
    border: 1px solid var(--line); border-radius: 5px;
    background: var(--input-bg); color: var(--text);
}
.mp-list { display: flex; flex-direction: column; gap: 10px; }
.mp-item { border: 1px solid var(--line); border-radius: 8px; padding: 9px 10px; background: var(--bg-card); }
.mp-item-head { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
.mp-item-kind { font-weight: 700; font-size: 12px; }
.mp-item-time { font-family: "IBM Plex Mono", monospace; font-size: 11px; color: var(--muted); }
.mp-item-bad {
    display: inline-flex; align-items: center; justify-content: center;
    width: 16px; height: 16px; border-radius: 50%;
    background: #c96a5e; color: #fff; font-size: 11px; font-weight: 700;
}
.mp-item-del {
    margin-left: auto; min-height: 0; padding: 0 6px; line-height: 1;
    border: none; background: none; color: var(--muted); font-size: 16px; cursor: pointer;
}
.mp-item-del:hover { color: #c96a5e; }
.mp-add { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }
.mp-add-btn {
    min-height: 0; padding: 5px 9px; font-size: 12px; cursor: pointer;
    border: 1px solid var(--line); border-radius: 6px;
    background: var(--bg-card); color: var(--text);
}
.mp-add-btn:hover { border-color: var(--accent); color: var(--accent); }
.mp-empty { margin: 0; color: var(--muted); font-size: 12px; line-height: 1.5; }
.mp-stats { margin-top: 16px; display: flex; flex-direction: column; gap: 5px; }
.mp-stat { display: flex; justify-content: space-between; }
.mp-stat-label { color: var(--muted); }
.mp-stat-value { font-family: "IBM Plex Mono", monospace; font-weight: 600; }
.mp-legend { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 8px; font-size: 11px; color: var(--muted); }
.mp-legend-item { display: inline-flex; align-items: center; gap: 5px; }
.mp-legend-item::before { content: ""; width: 14px; height: 2px; border-radius: 1px; }
.mp-legend-item.is-cut::before { background: #0f766e; }
.mp-legend-item.is-rapid::before { background: #c96a5e; }
.mp-legend-item.is-plunge::before { background: #b45309; height: 3px; }
.mp-notes { margin: 0; padding-left: 18px; font-size: 12px; line-height: 1.6; color: var(--muted); }
.mp-notes li.is-error { color: #c96a5e; font-weight: 600; }
.mp-export {
    width: 100%; margin-top: 18px; padding: 9px 12px;
    border: none; border-radius: 7px; cursor: pointer;
    background: var(--accent); color: #fff; font-weight: 700; font-size: 13px;
}
.mp-export:disabled { opacity: 0.45; cursor: not-allowed; }

/* Przyciski przeciagania widoku — geometria kafla wstazki w miniaturze. */
.viewport-controls-3d .drag-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    padding: 0 !important;
    border-radius: 7px !important;
    color: var(--muted);
}

.viewport-controls-3d .drag-btn svg {
    width: 18px;
    height: 18px;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.6;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.viewport-controls-3d .drag-btn:hover {
    background: var(--soft) !important;
    color: var(--text);
}

.viewport-controls-3d .drag-btn.is-active,
.viewport-controls-3d .drag-btn:active {
    background: var(--accent-soft) !important;
    color: var(--accent);
}


/* ── Suwak warstw i pasek symulacji przy plotnie ──────────────────────

   Plansze 4 i 6 stawiaja te dwie kontrolki PRZY PLOTNIE, a nie w panelu
   bocznym: obie sluza do patrzenia na sciezke, wiec reka ma byc blisko
   tego, na co patrzy. Suwak pionowy przy prawej krawedzi odpowiada osi Z
   — w gore znaczy wyzej i przy frezowaniu, i przy druku. */

.layer-slider {
    position: absolute;
    /* PONIZEJ gizma osi (siedzi na 8 px, ma 96 px wysokosci, a pod nim
       rzad przyciskow do 132 px) — wczesniej zaczynal sie pod gizmem, ktore
       ma wyzszy z-index, wiec przejmowalo klikniecia i suwak nie dawal sie
       przesunac. */
    top: 140px;
    right: 12px;
    bottom: 96px;
    z-index: 95;
    /* Waska kolumna: odczyt lamie sie na dwie krotkie linie, zamiast
       rozciagac suwak na 138 px i wchodzic pod klaster widoku. */
    width: 46px;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 8px;
    padding: 10px 8px;
    border: 1px solid var(--line);
    border-radius: 10px;
    background: var(--panel-solid);
    box-shadow: var(--shadow-md);
}

.layer-slider-input {
    flex: 1;
    width: 24px;
    min-height: 80px;
    writing-mode: vertical-lr;
    direction: rtl;                 /* gora suwaka = wieksza wartosc */
    accent-color: var(--accent);
    cursor: pointer;
}

.layer-slider-cap,
.layer-slider-value {
    font-family: var(--font-mono);
    font-size: 9px;
    line-height: 1.25;
    color: var(--muted);
    text-align: center;
    white-space: pre-line;
}
.layer-slider-value { color: var(--text); font-weight: 600; }

.sim-bar {
    position: absolute;
    left: 50%;
    bottom: 16px;
    transform: translateX(-50%);
    z-index: 60;
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 10px;
    border: 1px solid var(--line);
    border-radius: 10px;
    background: var(--panel-solid);
    box-shadow: var(--shadow-md);
}

.sim-btn {
    width: 28px;
    height: 28px;
    min-height: auto;
    padding: 0;
    border: 1px solid var(--line-strong);
    border-radius: 6px;
    background: none;
    color: var(--text);
    font-size: 12px;
    cursor: pointer;
}
.sim-btn:hover { background: var(--hover-bg); }
.sim-btn.is-active { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }

.sim-progress {
    width: 260px;
    accent-color: var(--accent);
    cursor: pointer;
}

.sim-readout {
    font-family: var(--font-mono);
    font-size: 11px;
    color: var(--muted);
    min-width: 108px;
    text-align: right;
}


/* ── Biblioteka narzedzi (plansza 5) ────────────────────────────────── */

.lib-card-host { width: min(920px, 92vw); }
.lib-body { display: flex; flex-direction: column; gap: 12px; }

.lib-filters {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr)) minmax(0, 1.2fr);
    gap: 8px;
    align-items: end;
}
.lib-filter { display: flex; flex-direction: column; gap: 4px; }
.lib-filter-label {
    font-size: 9px;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--muted);
}
.lib-filter-input,
.lib-search {
    padding: 6px 8px;
    border: 1px solid var(--line-strong);
    border-radius: 6px;
    background: var(--panel);
    color: var(--text);
    font-size: 12px;
    min-height: auto;
}

.lib-columns {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 260px;
    gap: 16px;
    align-items: start;
}

.lib-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
    gap: 8px;
    max-height: 52vh;
    overflow-y: auto;
    padding-right: 4px;
}

.lib-aside {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 12px;
    border: 1px solid var(--line);
    border-radius: 8px;
    background: var(--accent-soft);
}
.lib-aside-title {
    margin: 0;
    font-size: 9px;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--accent);
}

.lib-card {
    display: flex;
    flex-direction: column;
    gap: 3px;
    padding: 9px 10px;
    border: 1px solid var(--line);
    border-radius: 8px;
    background: var(--panel-solid);
    text-align: left;
    min-height: auto;
    cursor: pointer;
    color: var(--text);
}
.lib-card:hover { border-color: var(--accent); }
.lib-card.is-active { border-color: var(--accent); background: var(--accent-soft); }
.lib-card.is-warn { border-color: var(--danger); }

.lib-card-name { font-size: 12px; font-weight: 600; }
.lib-card-spec { font-family: var(--font-mono); font-size: 10px; color: var(--muted); }
.lib-card-warn { font-size: 10px; color: var(--danger); }
.lib-empty { font-size: 11px; color: var(--muted); }


/* ── Ekran eksportu G-code (plansza 4) ──────────────────────────────

   Arkusz przy prawej krawedzi, a nie modal na cala szerokosc: podglad
   sciezki zostaje widoczny, bo to on jest tresci a tego ekranu.
   Przelaczniki zmieniaja to, co rysuje plotno — drugi rysunek tej samej
   sciezki oznaczalby drugie miejsce, w ktorym moze sie rozjechac. */

.exp-sheet {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    width: min(360px, 92vw);
    z-index: 2400;
    display: flex;
    flex-direction: column;
    background: var(--panel-solid);
    border-left: 1px solid var(--line-strong);
    box-shadow: var(--shadow-lg);
}

.exp-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 14px 16px;
    border-bottom: 1px solid var(--line);
}
.exp-title { margin: 0; font-size: 14px; font-weight: 700; }

.exp-body {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    padding: 12px 16px 16px;
}

.exp-section {
    margin: 16px 0 6px;
    font-size: 9px;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--muted);
}
.exp-section:first-child { margin-top: 0; }

.exp-list { display: flex; flex-direction: column; gap: 3px; }
.exp-op {
    display: grid;
    grid-template-columns: 16px 1fr auto;
    gap: 8px;
    align-items: center;
    padding: 5px 7px;
    border-radius: 5px;
    background: var(--panel);
    font-size: 12px;
}
.exp-op.is-bad { border-left: 2px solid var(--danger); }
.exp-op-index { font-family: var(--font-mono); font-size: 10px; color: var(--muted); }
.exp-op-time { font-family: var(--font-mono); font-size: 11px; color: var(--muted); }

.exp-row {
    display: flex;
    justify-content: space-between;
    gap: 12px;
    padding: 4px 0;
    font-size: 12px;
}
.exp-row-label { color: var(--muted); }
.exp-row-value { font-family: var(--font-mono); }
.exp-row-value.is-strong { font-weight: 700; color: var(--text); }

.exp-toggle {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 4px 0;
    font-size: 12px;
    cursor: pointer;
}

.exp-select {
    width: 100%;
    padding: 6px 8px;
    border: 1px solid var(--line-strong);
    border-radius: 6px;
    background: var(--panel);
    color: var(--text);
    font-size: 12px;
    min-height: auto;
}

.exp-warn { margin: 6px 0 0; font-size: 11px; color: var(--danger); }
.exp-ok { margin: 6px 0 0; font-size: 11px; color: var(--muted); }

.exp-foot {
    display: flex;
    gap: 8px;
    justify-content: flex-end;
    padding: 12px 16px;
    border-top: 1px solid var(--line);
}


/* ── Ekrany maszyn (plansze 7-9) ────────────────────────────────────── */

.mach-sheet { width: min(420px, 96vw); }
.mach-lead { margin: 0 0 12px; font-size: 12px; color: var(--muted); line-height: 1.5; }

.mach-grid { display: flex; flex-direction: column; gap: 8px; }

.mach-card {
    display: flex;
    flex-direction: column;
    gap: 4px;
    padding: 10px 12px;
    border: 1px solid var(--line);
    border-radius: 8px;
    background: var(--panel);
}
.mach-card.is-active { border-color: var(--accent); background: var(--accent-soft); }
.mach-card.is-warn { border-color: var(--danger); }
.mach-card-head { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }
.mach-card-name { font-size: 13px; font-weight: 600; }
.mach-card-kind { font-size: 10px; color: var(--muted); }
.mach-card-spec { font-family: var(--font-mono); font-size: 11px; color: var(--muted); }
.mach-card-warn { font-size: 10px; color: var(--danger); }
.mach-card-own { font-size: 10px; color: var(--accent); }
.mach-card-actions { display: flex; gap: 6px; justify-content: flex-end; margin-top: 4px; }

.mach-field { display: flex; flex-direction: column; gap: 4px; margin-bottom: 10px; }
.mach-label {
    font-size: 9px;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--muted);
}
.mach-input {
    width: 100%;
    padding: 6px 8px;
    border: 1px solid var(--line-strong);
    border-radius: 6px;
    background: var(--panel);
    color: var(--text);
    font-size: 12px;
    min-height: auto;
}
.mach-hint { font-size: 11px; color: var(--muted); line-height: 1.45; }

.mach-steps { display: flex; gap: 6px; margin-bottom: 14px; flex-wrap: wrap; }
.mach-step {
    padding: 3px 8px;
    border: 1px solid var(--line);
    border-radius: 999px;
    font-size: 10px;
    color: var(--muted);
}
.mach-step.is-active { border-color: var(--accent); color: var(--accent); font-weight: 700; }
.mach-step.is-done { color: var(--text); }

.mach-area { width: 100%; height: auto; margin: 8px 0; }
.mach-area-bed { fill: var(--accent-soft); stroke: var(--accent); stroke-width: 1.5; }
.mach-area-origin { fill: var(--danger); }
.mach-area-label { fill: var(--muted); font-size: 10px; font-family: "IBM Plex Mono", monospace; }

.mach-params { display: flex; flex-direction: column; gap: 4px; }
.mach-param {
    display: grid;
    grid-template-columns: 1fr auto 120px;
    gap: 8px;
    align-items: center;
    padding: 4px 6px;
    border-radius: 5px;
}
.mach-param:hover { background: var(--hover-bg); }
.mach-param-path { font-family: var(--font-mono); font-size: 11px; }
.mach-param-badge {
    padding: 1px 6px;
    border-radius: 999px;
    background: var(--accent);
    color: var(--accent-ink);
    font-size: 9px;
    font-weight: 700;
    text-transform: uppercase;
}
.mach-param-input { font-size: 11px; padding: 3px 6px; }

.mach-foot-row { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 14px; }

/* Pole z lista i przyciskiem obok — np. maszyna plus wejscie do jej ustawien. */
.mp-inline { display: flex; gap: 6px; align-items: center; }
.mp-inline > select { flex: 1; min-width: 0; }
.mp-icon-btn {
    width: 28px;
    height: 28px;
    min-height: auto;
    padding: 0;
    border: 1px solid var(--line-strong);
    border-radius: 6px;
    background: none;
    color: var(--muted);
    cursor: pointer;
}
.mp-icon-btn:hover { background: var(--hover-bg); color: var(--text); }


/* ── Belka pod plotnem: przelacznik trybu + tresc trybu ───────────────

   Plansze 2a/2b/2c pokazuja TE SAMA belke w trzech trybach. Po lewej trzy
   ikony, po prawej tresc wybranego. Trzy komplety naraz rosly do 980 px
   przy planszowych 44 — i tak nikt nie patrzy na wszystkie trzy jednoczesnie. */

.constraint-palette {
    position: fixed;
    left: 50%;
    bottom: 40px;
    transform: translateX(-50%);
    z-index: 1200;
    display: flex;
    align-items: center;
    gap: 8px;
    max-width: min(900px, 96vw);
    height: 44px;
    padding: 0 8px;
    border: 1px solid var(--line);
    border-radius: 12px;
    background: var(--panel-solid);
    box-shadow: var(--shadow-md);
}

.palette-modes { display: flex; align-items: center; gap: 2px; }
.constraint-palette .tab-ico { width: 16px; height: 16px; }
.palette-panel { display: none; align-items: center; gap: 3px; }
.palette-sep { width: 1px; height: 22px; background: var(--line); }

.palette-btn {
    position: relative;
    width: 30px;
    height: 30px;
    min-height: auto;
    padding: 0;
    border: 1px solid transparent;
    border-radius: 8px;
    background: none;
    color: var(--muted);
    font-size: 13px;
    line-height: 1;
    cursor: pointer;
}
.palette-btn:hover:not(:disabled) { background: var(--hover-bg); color: var(--text); border-color: var(--line); }
.palette-btn.is-active {
    background: var(--accent-soft);
    border-color: var(--accent);
    color: var(--accent);
}
.palette-btn:disabled { opacity: 0.35; cursor: default; }

.palette-readout {
    padding: 0 8px;
    font-family: var(--font-mono);
    font-size: 11px;
    color: var(--muted);
    white-space: nowrap;
}

/* Rozstaw siatki w belce: edytowalny, ale wyglada jak odczyt — pole bez
   ramki, ramka pojawia sie dopiero pod fokusem. */
.palette-grid-size {
    display: inline-flex;
    align-items: center;
    gap: 3px;
    cursor: text;
}
.palette-grid-size input {
    width: 40px;
    padding: 2px 4px;
    border: 1px solid transparent;
    border-radius: 4px;
    background: transparent;
    font: inherit;
    color: var(--text);
    text-align: right;
    -moz-appearance: textfield;
}
.palette-grid-size input::-webkit-outer-spin-button,
.palette-grid-size input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.palette-grid-size input:hover { border-color: var(--line); }
.palette-grid-size input:focus { outline: none; border-color: var(--accent); background: var(--panel, transparent); }

/* Wiezy w belce: ten sam rozmiar co reszta, plus licznik z planszy 2b. */
.constraint-palette .tool-grid.constraint-grid { display: flex; gap: 3px; flex-wrap: nowrap; }
.constraint-palette .constraint-btn {
    position: relative;
    width: 30px;
    height: 30px;
    min-height: auto;
    background: none;
    border-color: transparent;
    border-radius: 8px;
    font-size: 13px;
    line-height: 1;
}
.constraint-palette .constraint-btn:hover:not(:disabled) { background: var(--hover-bg); border-color: var(--line); }
/* Licznik mowi "juz sa dwa", a nie tylko "da sie" — bez niego ikona nie
   niesie zadnej informacji o stanie szkicu. */
.constraint-palette .constraint-btn[data-count]:not([data-count=""])::after {
    content: attr(data-count);
    position: absolute;
    top: -2px;
    right: -2px;
    min-width: 13px;
    height: 13px;
    padding: 0 3px;
    border-radius: 999px;
    background: var(--accent);
    color: var(--accent-ink);
    font-family: var(--font-mono);
    font-size: 9px;
    line-height: 13px;
}

/* Snapy: same ikony — nazwa trybu i tak stoi w pasku statusu. */
.constraint-palette .snap-menu-inline { display: flex; gap: 3px; flex-wrap: nowrap; }
.constraint-palette .snap-menu-item {
    width: 30px;
    height: 30px;
    min-height: auto;
    padding: 0;
    justify-content: center;
    border: 1px solid transparent;
    border-radius: 8px;
    background: none;
    color: var(--muted);
    cursor: pointer;
}
.constraint-palette .snap-menu-item span { display: none; }
.constraint-palette .snap-menu-item:hover { background: var(--hover-bg); color: var(--text); border-color: var(--line); }
.constraint-palette .snap-menu-item.is-active {
    background: var(--accent-soft);
    border-color: var(--accent);
    color: var(--accent);
}

.constraint-palette .history-timeline { max-width: 420px; }

/* Opis trybu po lewej stronie paska statusu, jak na planszach 2a/2b/2c. */

/* Suwak warstw zajmuje prawa krawedz — klaster widoku ustepuje mu miejsca. */
body.has-layer-slider .viewport-controls-3d { right: 70px; }

/* Wybor plaszczyzny przekroju — pigulki zamiast listy rozwijanej. */
.section-pills { display: flex; flex-wrap: wrap; gap: 4px; }
.section-pill {
    padding: 4px 10px;
    border: 1px solid var(--line-strong);
    border-radius: 999px;
    background: none;
    color: var(--text);
    font-size: 11px;
    min-height: auto;
    cursor: pointer;
}
.section-pill:hover { background: var(--hover-bg); }
.section-pill.is-active {
    background: var(--accent-soft);
    border-color: var(--accent);
    color: var(--accent);
    font-weight: 600;
}
.section-pills-empty { font-size: 11px; color: var(--muted); line-height: 1.4; }
.section-plane-fallback { display: none; }
.section-info {
    font-size: 11px;
    color: var(--muted);
    font-family: var(--font-mono);
    margin: 6px 0 2px;
    min-height: 14px;
}
.section-pill.is-active[data-plane-id="__face__"] { border-style: dashed; }

/* Okno pytania o tekst — zamiennik prompt(), ktory jest zablokowany
   w przegladarkach z sandboxem. */
.ask-card { width: min(420px, 92vw); }
.ask-label { margin: 0 0 10px; font-size: 13px; line-height: 1.45; white-space: pre-line; }
.ask-input {
    width: 100%;
    padding: 8px 10px;
    border: 1px solid var(--line-strong);
    border-radius: 6px;
    background: var(--panel);
    color: var(--text);
    font-size: 13px;
}
.ask-foot { display: flex; gap: 8px; justify-content: flex-end; padding: 12px 16px; border-top: 1px solid var(--line); }

/* ─────────────── Konto i chmura ─────────────── */

/* BRAMKA NA WEJSCIU. Aplikacja nie ma trybu offline, wiec dopoki nie ma
   sesji, nie pokazujemy szkicownika — nie po to, zeby cos ukryc, tylko
   zeby nikt nie zaczal rysowac czegos, czego i tak nie da sie policzyc
   ani zapisac. Interfejs pod spodem jest odciety takze od klawiatury. */
body.is-locked > *:not(#auth-modal):not(#toast-container) {
    filter: blur(3px);
    pointer-events: none;
    user-select: none;
}

.auth-gate {
    background: var(--bg);
    backdrop-filter: none;
}

.auth-lead {
    margin: 0 0 14px;
    color: var(--muted);
    font-size: 13px;
    line-height: 1.5;
}


/* Ekran chmury jest szerszy od arkusza eksportu: karta projektu musi
   pomiescic nazwe, rozmiar, date i cztery przyciski w jednym rzedzie. */
.cloud-sheet { width: min(480px, 96vw); }

/* ── Sekcja konta w ekranie chmury ──
   Adres e-mail dostaje CALY wiersz i lamie sie na dowolnym znaku: adresy
   firmowe bywaja dluzsze niz arkusz i nie maja gdzie sie zlamac po slowie. */
.cloud-account {
    text-transform: none;
    letter-spacing: normal;
    font-size: 12px;
    font-weight: 400;
    padding-bottom: 14px;
    border-bottom: 1px solid var(--line);
}
.cloud-account .exp-section-head {
    font-size: 9px;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--muted);
}
.cloud-account-mail {
    margin-top: 4px;
    font-size: 14px;
    font-weight: 600;
    color: var(--text);
    overflow-wrap: anywhere;
    line-height: 1.3;
}
.cloud-account-plan {
    display: flex;
    flex-wrap: wrap;
    gap: 4px 10px;
    justify-content: space-between;
    margin-top: 8px;
}
.cloud-account-plan-name { font-weight: 700; color: var(--text); }
.cloud-account-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-top: 12px;
}
/* Kasowanie konta stoi z prawej, z dala od wylogowania — dwa klikniecia
   obok siebie, a skutki nieporownywalne. */
.cloud-account-actions .cloud-danger { margin-left: auto; }
.cloud-account .auth-hint { margin-top: 8px; }

.cloud-quota { text-transform: none; letter-spacing: normal; font-size: 12px; font-weight: 400; }
.cloud-quota .exp-row-label { font-weight: 700; color: var(--text); }

.cloud-bar {
    margin-top: 8px;
    height: 8px;
    border-radius: 999px;
    background: var(--soft);
    overflow: hidden;
}
.cloud-bar-fill {
    height: 100%;
    border-radius: 999px;
    background: var(--accent);
    transition: width 160ms ease;
}
/* Kolor niesie ten sam prog, co logika w account.js: ostrzezenie od 80%,
   czerwien dopiero przy pelnym magazynie. */
.cloud-bar-fill.is-warn { background: var(--warn); }
.cloud-bar-fill.is-full { background: var(--danger); }

.cloud-list { text-transform: none; letter-spacing: normal; font-weight: 400; display: flex; flex-direction: column; gap: 8px; }

.cloud-card {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 10px 12px;
    border: 1px solid var(--line);
    border-radius: 8px;
    background: var(--bg-card);
}
.cloud-card.is-current { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent-soft); }
.cloud-card-name { font-size: 13px; font-weight: 600; color: var(--text); }
.cloud-card-meta { font-size: 11px; color: var(--muted); }
.cloud-card-actions { display: flex; flex-wrap: wrap; gap: 6px; }
.cloud-card-actions .ribbon-action { padding: 4px 10px; font-size: 11px; }

.cloud-danger { color: var(--danger); border-color: var(--danger-soft); }
.cloud-empty { text-transform: none; letter-spacing: normal; font-weight: 400; }
.cloud-support-btn { border-color: var(--warn); }

/* Preferencje w ekranie konta: etykieta z lewej, przelacznik segmentowy
   z prawej — ten sam .seg-switch, ktory stal kiedys w naglowku. */
.cloud-prefs {
    text-transform: none;
    letter-spacing: normal;
    font-size: 12px;
    font-weight: 400;
    margin-top: 14px;
    padding-top: 14px;
    border-top: 1px solid var(--line);
}
.cloud-prefs .exp-section-head {
    font-size: 9px;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--muted);
}
.cloud-prefs-row {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 12px;
    padding: 6px 0;
}
.cloud-prefs-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-top: 12px;
}
.cloud-stats .exp-row { padding: 3px 0; }

/* ─────────────── Okno logowania ─────────────── */

.auth-card { width: min(380px, 94vw); }
.auth-body { display: flex; flex-direction: column; gap: 12px; }

.auth-tabs { display: flex; gap: 4px; }
.auth-tab {
    flex: 1;
    padding: 7px 10px;
    font: inherit;
    font-size: 12px;
    color: var(--muted);
    background: var(--soft);
    border: 1px solid transparent;
    border-radius: 6px;
    cursor: pointer;
}
/* Wybrana zakladka na PELNYM akcencie: przy tle --accent-soft (jasny teal)
   bialy --accent-ink byl praktycznie niewidoczny. */
.auth-tab.is-active {
    color: var(--accent-ink);
    background: var(--accent);
    border-color: var(--accent);
    font-weight: 600;
}

.auth-field { display: flex; flex-direction: column; gap: 4px; }
.auth-label { font-size: 11px; font-weight: 600; color: var(--muted); }

.auth-hint { margin: 0; font-size: 11px; color: var(--muted); }
.auth-hint--warn { color: var(--warn); }

.auth-error {
    margin: 0;
    padding: 7px 10px;
    font-size: 12px;
    color: var(--danger);
    background: var(--danger-soft);
    border-radius: 6px;
}

/* Plakietka konta w belce gornej. Pokazuje litere adresu i cienki pasek
   zajetosci — tyle, ile da sie odczytac katem oka. */
.account-btn { display: inline-flex; align-items: center; gap: 6px; }
.account-btn .account-dot {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 18px;
    height: 18px;
    border-radius: 999px;
    background: var(--accent-soft);
    color: var(--accent);
    font-size: 10px;
    font-weight: 700;
    text-transform: uppercase;
}

/* ── Ekran "Licencje open source" ──
   Korzysta z ramy .exp-sheet (ten sam arkusz z prawej co eksport G-code) —
   wlasny szkielet oznaczalby druga definicje tego samego okna. Tutaj tylko
   to, czego eksport nie ma: notka OCCT i lista skladnikow. */
.lic-intro {
    margin: 0 0 10px;
    font-size: 12px;
    line-height: 1.6;
    color: var(--muted);
}

/* Notka o OCCT jest wymogiem licencji, wiec ma byc pierwsza rzecza, ktora
   widac po otwarciu — stad ramka w kolorze akcentu, nie zwykly akapit. */
.lic-notice {
    padding: 10px 12px;
    border: 1px solid var(--accent);
    border-radius: 6px;
    background: color-mix(in srgb, var(--accent) 8%, transparent);
    font-size: 12px;
    line-height: 1.6;
    color: var(--text);
}

.lic-list { display: flex; flex-direction: column; gap: 8px; }

.lic-item {
    padding: 9px 11px;
    border: 1px solid var(--line);
    border-radius: 6px;
    background: var(--bg-card);
}
/* Skladniki z obowiazkiem notki (OCCT, czcionki) odrozniaja sie od reszty. */
.lic-item.is-key { border-color: var(--line-strong); }

.lic-item-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 8px;
    margin-bottom: 3px;
}
.lic-name { font-size: 12px; font-weight: 700; color: var(--text); }
.lic-badge {
    flex: none;
    font-size: 10px;
    color: var(--muted);
    text-align: right;
}
.lic-role { font-size: 11px; line-height: 1.5; color: var(--muted); }
.lic-meta {
    display: flex;
    justify-content: space-between;
    gap: 8px;
    margin-top: 5px;
    font-size: 10px;
    color: var(--muted);
}
.lic-link { color: var(--accent); text-decoration: none; }
.lic-link:hover { text-decoration: underline; }

/* ── Zamrozona klatka na wejsciu w render foto ──────────────────────────
   Kopia ostatniej klatki podgladu lezaca na plotnie, zeby przelaczenie
   trybu nie bylo widoczne jako mrugniecie. Krycie i rozmycie steruje
   JavaScript (patrz przenikanieStartu w src/path_tracer.js); tutaj sa
   tylko przejscia, zeby zmiany szly plynnie miedzy klatkami, oraz
   pulsowanie na czas, gdy pod spodem nie ma jeszcze ani jednej probki. */
.cad-foto-zamrozenie {
    opacity: 1;
    filter: blur(0px);
    transition: opacity 120ms linear, filter 120ms linear;
}
.cad-foto-zamrozenie--czeka {
    animation: cad-foto-czekanie 1.6s ease-in-out infinite;
}
@keyframes cad-foto-czekanie {
    0%, 100% { filter: blur(0px); }
    50%      { filter: blur(3px); }
}
@media (prefers-reduced-motion: reduce) {
    /* Pulsowanie jest sygnalem „pracuje", a nie trescia — kto prosi
       o mniej ruchu, dostaje nieruchoma klatke i sam pasek postepu. */
    .cad-foto-zamrozenie--czeka { animation: none; }
    .cad-foto-zamrozenie { transition-duration: 240ms; }
}

/* ─── Warsztaty i części z chmury (ekran chmury) ─── */
.cloud-teams-tabs { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-bottom: 8px; }
.cloud-teams-tabs .seg-switch { flex-wrap: wrap; }
.cloud-members-head { font-size: 11px; font-weight: 600; color: var(--muted); margin-top: 8px; }
.cloud-members { display: flex; flex-direction: column; gap: 2px; margin-top: 4px; }
.cloud-member { display: flex; align-items: center; gap: 8px; font-size: 12px; padding: 3px 0; }
.cloud-member-mail { flex: 1; min-width: 0; overflow-wrap: anywhere; color: var(--text); }
.cloud-member-role { font-size: 11px; color: var(--muted); white-space: nowrap; }
.cloud-member-btn { padding: 2px 8px; font-size: 11px; }
.cloud-card-reserved { font-size: 11px; color: var(--warn); margin-top: 2px; }
/* Sekcja eksportu wersalikuje wszystko (.exp-section) — adresy, podpowiedz
   i informacja "kto edytuje" maja zostac w naturalnej pisowni. */
.cloud-teams .auth-hint, .cloud-member, .cloud-card-reserved { text-transform: none; }

/* ─── Wybór części z chmury ─── */
.cloud-picker { width: min(480px, 94vw); }
.cloud-picker-list { display: flex; flex-direction: column; gap: 4px; max-height: 50vh; overflow-y: auto; margin-top: 8px; }
.cloud-picker-row {
    display: flex; flex-direction: column; align-items: flex-start; gap: 2px;
    width: 100%; padding: 8px 10px; border: 1px solid var(--line); border-radius: 8px;
    background: var(--panel); color: var(--text); text-align: left; cursor: pointer; font: inherit;
}
.cloud-picker-row:hover { border-color: var(--accent); background: var(--panel-2, var(--panel)); }
.cloud-picker-name { font-weight: 600; font-size: 13px; }
.cloud-picker-meta { font-size: 11px; color: var(--muted); }

/* ─── Pasek edycji części w kontekście złożenia ─── */
.context-bar {
    position: fixed; top: 52px; left: 50%; transform: translateX(-50%); z-index: 60;
    display: flex; align-items: center; gap: 10px; flex-wrap: wrap; justify-content: center;
    max-width: min(760px, 94vw); padding: 8px 14px; border-radius: 10px;
    background: var(--panel); color: var(--text); border: 1px solid var(--accent);
    box-shadow: 0 6px 20px rgba(0, 0, 0, 0.18); font-size: 12px;
}
.context-bar-text { flex: 1 1 260px; }
.context-bar .ribbon-action { padding: 4px 10px; font-size: 12px; }

/* ─── Foldery w chmurze ─── */
.cloud-crumbs { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; margin-bottom: 8px; text-transform: none; letter-spacing: normal; }
.cloud-crumb {
    padding: 2px 6px; border: 1px solid transparent; border-radius: 6px; background: transparent;
    color: var(--accent); font: inherit; font-size: 12px; cursor: pointer;
}
.cloud-crumb:hover { background: var(--hover-bg); }
.cloud-crumb.is-current { color: var(--text); font-weight: 600; cursor: default; }
.cloud-crumb-sep { color: var(--muted); font-size: 12px; }
.cloud-folder-bar { display: flex; gap: 6px; margin-bottom: 4px; }
.cloud-folder-bar .ribbon-action { padding: 4px 10px; font-size: 11px; }
.cloud-folder {
    display: flex; align-items: center; justify-content: space-between; gap: 8px; flex-wrap: wrap;
    padding: 6px 10px; border: 1px dashed var(--line); border-radius: 8px;
}
.cloud-folder-main {
    flex: 1; min-width: 0; display: flex; flex-direction: column; align-items: flex-start; gap: 2px;
    padding: 2px 0; border: 0; background: transparent; color: var(--text); font: inherit; text-align: left; cursor: pointer;
}
.cloud-folder-main:hover .cloud-folder-name { color: var(--accent); }
.cloud-folder-name { font-size: 13px; font-weight: 600; text-transform: none; letter-spacing: normal; }

/* ─── Wybór miejsca zapisu (polka + folder) ─── */
.cloud-loc { width: min(520px, 94vw); }
.cloud-loc-tree { display: flex; flex-direction: column; gap: 2px; max-height: 50vh; overflow-y: auto; margin-top: 8px; }
.cloud-loc-row {
    display: flex; align-items: center; gap: 8px; width: 100%; padding: 6px 10px;
    border: 1px solid transparent; border-radius: 6px; background: transparent;
    color: var(--text); text-align: left; cursor: pointer; font: inherit; font-size: 13px;
}
.cloud-loc-row:hover { background: var(--hover-bg); }
.cloud-loc-row.is-selected { background: var(--accent-soft); border-color: var(--accent); }
.cloud-loc-row:disabled { color: var(--muted); cursor: not-allowed; }
.cloud-loc-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cloud-loc-meta { font-size: 11px; color: var(--muted); }
.cloud-loc-bar { display: flex; gap: 6px; margin-top: 8px; }
.cloud-loc-bar .ribbon-action { padding: 4px 10px; font-size: 11px; }


/* ═══════════════ Plansza 0: bramka logowania na caly ekran ═══════════════ */
.auth-gate { padding: 0; align-items: stretch; justify-content: stretch; }
.auth-split {
    display: grid;
    grid-template-columns: minmax(0, 1.3fr) minmax(360px, 1fr);
    width: 100%;
    height: 100%;
    background: var(--bg);
}
.auth-hero {
    position: relative;
    display: flex;
    flex-direction: column;
    padding: 40px 48px;
    overflow: hidden;
    background-color: var(--soft);
    background-image:
        linear-gradient(var(--line) 1px, transparent 1px),
        linear-gradient(90deg, var(--line) 1px, transparent 1px);
    background-size: 24px 24px;
    border-right: 1px solid var(--line);
}
.auth-brand { display: flex; align-items: center; gap: 10px; }
.auth-brand-mark {
    display: grid;
    place-items: center;
    width: 34px;
    height: 34px;
    border-radius: 9px;
    background: var(--accent);
    color: #fff;
}
.auth-brand-mark svg { width: 18px; height: 18px; }
.auth-brand-name { font-size: 15px; font-weight: 700; color: var(--text); }
.auth-hero-body { margin: auto 0; max-width: 560px; }
.auth-hero-title {
    margin: 0;
    font-size: clamp(30px, 4vw, 46px);
    line-height: 1.1;
    font-weight: 800;
    letter-spacing: -0.02em;
    color: var(--text);
}
.auth-hero-sub { margin: 18px 0 0; font-size: 15px; line-height: 1.5; color: var(--muted); max-width: 520px; }
.auth-points { display: flex; flex-wrap: wrap; gap: 8px 26px; margin: 22px 0 0; padding: 0; list-style: none; }
.auth-points li { font-size: 13px; color: var(--text); }
.auth-points li::before { content: "✓"; margin-right: 8px; color: var(--accent); font-weight: 700; }
.auth-art { margin-top: auto; max-width: 440px; color: var(--accent); }
.auth-art svg { width: 100%; height: auto; stroke: currentColor; stroke-width: 2; }
.auth-art-solid path { fill: var(--accent-soft); stroke: var(--accent); stroke-width: 1.5; }
.auth-art-side { opacity: 0.8; }
.auth-art-side2 { opacity: 0.6; }
.auth-art-inner { opacity: 0.9; }
.auth-art-dim path { stroke: var(--accent); stroke-width: 2; fill: none; }
.auth-art-dim circle { fill: var(--bg); stroke: var(--accent); stroke-width: 2; }
.auth-art-dim text { fill: var(--accent); stroke: none; font-family: inherit; letter-spacing: 0.02em; }
.auth-art-dim .auth-art-arrow { fill: var(--accent); stroke-width: 1; }

.auth-panel {
    display: flex;
    /* Srodkowanie przez margin: auto, nie align-items: center — przy formularzu
       wyzszym niz okno (rejestracja na niskim ekranie) center obcina gore
       i nie da sie do niej doscrollowac. */
    align-items: flex-start;
    justify-content: center;
    padding: 40px 48px;
    overflow-y: auto;
    background: var(--panel-solid);
}
.auth-form { width: min(440px, 100%); margin: auto 0; display: flex; flex-direction: column; gap: 12px; }
.auth-form-title { margin: 0; font-size: 26px; font-weight: 800; letter-spacing: -0.01em; color: var(--text); }
.auth-form .auth-lead { margin: -4px 0 8px; font-size: 13px; line-height: 1.5; color: var(--muted); }
.auth-form .ask-input { padding: 12px 14px; font-size: 14px; }
.auth-pass { position: relative; }
.auth-pass .ask-input { width: 100%; padding-right: 42px; }
.auth-eye {
    position: absolute;
    top: 50%;
    right: 8px;
    transform: translateY(-50%);
    width: 30px;
    height: 30px;
    min-height: auto;
    padding: 0;
    display: grid;
    place-items: center;
    border: none;
    border-radius: 6px;
    background: none;
    color: var(--muted);
    cursor: pointer;
}
.auth-eye svg { width: 18px; height: 18px; }
.auth-eye:hover, .auth-eye.is-on { color: var(--accent); }
.auth-submit {
    margin-top: 6px;
    padding: 13px 16px;
    border: none;
    border-radius: 10px;
    background: var(--accent);
    color: #fff;
    font-size: 15px;
    font-weight: 700;
    cursor: pointer;
}
.auth-submit:hover:not(:disabled) { filter: brightness(1.08); }
.auth-submit:disabled { opacity: 0.6; cursor: wait; }
.auth-switch { margin: 6px 0 0; font-size: 12px; color: var(--muted); }
.auth-link {
    padding: 0;
    min-height: auto;
    border: none;
    background: none;
    color: var(--accent);
    font-size: 12px;
    font-weight: 600;
    cursor: pointer;
    text-decoration: underline;
    text-underline-offset: 2px;
}
@media (max-width: 860px) {
    /* Jedna kolumna: hero nad formularzem, calosc przewija sie jako jeden
       slupek. Siatka o wysokosci 100% dzielila ekran na dwa wiersze, wiec
       hero obcinal punkty, a formularz wjezdzal pod niego. */
    .auth-split { display: flex; flex-direction: column; overflow-y: auto; }
    .auth-hero, .auth-panel { flex: none; overflow: visible; }
    .auth-hero { padding: 24px; border-right: none; border-bottom: 1px solid var(--line); }
    .auth-hero-body { margin: 18px 0; }
    .auth-art { display: none; }
    .auth-panel { padding: 24px; }
    .auth-form { margin: 0 auto; }
}

/* ═══════════════ Plansza 1: strona startowa po zalogowaniu ═══════════════ */
.home {
    position: fixed;
    inset: 0;
    z-index: 2300;   /* nad scena i panelami, pod ekranem chmury (2400) i modalami */
    overflow-y: auto;
    background: var(--bg);
}
.home-inner {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(300px, 400px);
    gap: 32px;
    max-width: 1440px;
    margin: 0 auto;
    padding: 36px 40px 48px;
}
.home-title { margin: 0; font-size: 28px; font-weight: 800; letter-spacing: -0.02em; color: var(--text); }
.home-sub { margin: 6px 0 22px; font-size: 14px; color: var(--muted); }
.home-actions { display: grid; grid-template-columns: minmax(260px, 400px) minmax(220px, 250px); gap: 14px; }
.home-actions-col { display: flex; flex-direction: column; gap: 14px; }
.home-action {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 14px;
    padding: 18px 20px;
    border: 1px solid var(--line-strong);
    border-radius: 14px;
    background: var(--panel-solid);
    text-align: left;
    min-height: auto;
    cursor: pointer;
    transition: border-color 120ms ease, background 120ms ease;
}
.home-action:hover { border-color: var(--accent); }
.home-action-icon { display: grid; place-items: center; width: 34px; height: 34px; border-radius: 9px; color: var(--muted); }
.home-action-icon svg { width: 20px; height: 20px; }
.home-action--primary {
    justify-content: space-between;
    min-height: 200px;
    border: 2px dashed var(--accent);
    background: var(--accent-soft);
}
.home-action--primary .home-action-icon { width: 50px; height: 50px; border-radius: 12px; background: var(--accent); color: #fff; }
.home-action--primary .home-action-icon svg { width: 26px; height: 26px; }
.home-action--primary .home-action-label { font-size: 18px; color: var(--accent); }
.home-action-label { font-size: 15px; font-weight: 700; color: var(--text); }
.home-action-note { margin-top: 3px; font-size: 12px; color: var(--muted); }

.home-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; margin: 30px 0 12px; }
.home-card .home-head { margin: 0 0 12px; }
.home-head-title { font-size: 11px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted); }
.home-head-note { font-size: 11px; color: var(--muted); }
.home-link { padding: 0; min-height: auto; border: none; background: none; color: var(--accent); font-size: 13px; font-weight: 600; cursor: pointer; }
.home-link:hover { text-decoration: underline; }
.home-empty { margin: 0; font-size: 13px; color: var(--muted); }

.home-projects { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 14px; }
.home-project {
    display: flex;
    flex-direction: column;
    padding: 0;
    min-height: auto;
    border: 1px solid var(--line-strong);
    border-radius: 14px;
    background: var(--panel-solid);
    overflow: hidden;
    text-align: left;
    cursor: pointer;
}
.home-project:hover { border-color: var(--accent); }
.home-project-thumb { display: grid; place-items: center; height: 120px; background: var(--soft); color: var(--muted); }
.home-thumb svg { width: 96px; height: 84px; }
.home-thumb .iso-top { fill: var(--accent-soft); }
.home-thumb .iso-side { fill: var(--soft); }
.home-thumb .iso-side2 { fill: var(--line); }
.home-project-body { padding: 12px 14px 14px; }
.home-project-name { font-size: 14px; font-weight: 700; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.home-project-meta { display: flex; align-items: center; gap: 8px; margin-top: 8px; font-size: 12px; color: var(--muted); }
.home-chip { padding: 2px 7px; border-radius: 5px; background: var(--soft); border: 1px solid var(--line); font-family: var(--font-mono, ui-monospace, monospace); font-size: 11px; max-width: 120px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.home-side { display: flex; flex-direction: column; gap: 20px; padding-top: 6px; }
.home-card { padding: 18px 20px; border: 1px solid var(--line-strong); border-radius: 14px; background: var(--panel-solid); }
.home-how { display: flex; flex-direction: column; gap: 14px; margin: 0; padding: 0; list-style: none; }
.home-how-step { display: flex; gap: 12px; align-items: flex-start; }
.home-how-num { flex: 0 0 auto; width: 22px; height: 22px; display: grid; place-items: center; border-radius: 6px; background: var(--accent-soft); color: var(--accent); font-family: var(--font-mono, ui-monospace, monospace); font-size: 11px; font-weight: 700; }
.home-how-title { font-size: 14px; font-weight: 700; color: var(--text); }
.home-how-desc { margin-top: 2px; font-size: 12.5px; line-height: 1.45; color: var(--muted); }
.home-guide {
    display: flex;
    align-items: center;
    gap: 12px;
    width: 100%;
    padding: 12px 14px;
    min-height: auto;
    border: 1px solid var(--line);
    border-radius: 10px;
    background: var(--soft);
    text-align: left;
    cursor: pointer;
}
.home-guide:hover { border-color: var(--accent); }
.home-guide-icon { display: grid; place-items: center; width: 36px; height: 36px; border-radius: 8px; background: var(--accent-soft); color: var(--accent); }
.home-guide-icon svg { width: 20px; height: 20px; }
.home-guide-body { flex: 1; min-width: 0; }
.home-guide-title { font-size: 14px; font-weight: 700; color: var(--text); }
.home-guide-note { font-size: 12px; color: var(--muted); }
.home-pill { padding: 3px 8px; border-radius: 6px; background: var(--accent-soft); color: var(--accent); font-family: var(--font-mono, ui-monospace, monospace); font-size: 11px; font-weight: 700; }
@media (max-width: 980px) {
    .home-inner { grid-template-columns: 1fr; padding: 24px; }
    .home-actions { grid-template-columns: 1fr; }
    .home-action--primary { min-height: 140px; }
}
