/*
   TabCode — Single stylesheet.

   Replaces Tailwind via CDN: the Play CDN compiles JIT in the browser on every
   load (~400 KB of JS, FOUC and 'unsafe-eval' in the CSP) — unacceptable in an
   editor that claims to be offline-first and fast.

   Design: flat. Zero radius, no decorative shadows, units in rem.
   System fonts: no external requests, clean CSP.
*/

/* --------------------------------------------------------------------------
   1. Tokens
   -------------------------------------------------------------------------- */

:root {
    --bg-editor: #272822;
    --bg-chrome: #1e1f1c;
    --bg-deep: #171814;
    --bg-hover: #49483e;
    --border: #3a3a32;

    --text: #f8f8f2;
    --text-muted: #75715e;
    --text-strong: #ffffff;

    --accent: #a6e22e;
    --accent-hover: #8ec024;
    --danger: #f92672;
    --warning: #e6db74;
    --info: #66d9ef;

    --sidebar-width: 15rem;
    --keyboard-offset: 0px;
    --safe-bottom: env(safe-area-inset-bottom, 0px);

    --font-ui: system-ui, -apple-system, 'Segoe UI', Roboto, Ubuntu, sans-serif;
    --font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', monospace;

    --duration: 0.15s;
}

/* The `hidden` attribute outranks any layout rule.

   Without !important this does NOT work: `[hidden]` has specificity (0,1,0), equal to
   `.dropdown`, and ties are resolved by file order. Since the reset comes first, any
   `.class { display: flex }` declared later would win — and that's how ALL menus ended
   up visible at once, with JS setting hidden=true and CSS ignoring it.

   `hidden` is an HTML contract, not a style suggestion. No layout overrides it. */
[hidden] {
    display: none !important;
}


:root[data-theme="light"] {
    --bg-editor: #ffffff;
    --bg-chrome: #f4f4f2;
    --bg-deep: #e6e6e2;
    --bg-hover: #dcdcd6;
    --border: #cfcfc8;

    --text: #232323;
    --text-muted: #6b6b60;
    --text-strong: #000000;

    --accent: #4c9a1f;
    --accent-hover: #3d7d19;
    --danger: #c1123f;
    --warning: #8a6d0b;
    --info: #1a7f96;
}

@media (prefers-reduced-motion: reduce) {
    :root { --duration: 0s; }
    * { animation: none !important; transition: none !important; }
}

/* --------------------------------------------------------------------------
   2. Reset e base
   -------------------------------------------------------------------------- */

*, *::before, *::after { box-sizing: border-box; }

html, body {
    height: 100vh;
    height: 100dvh;   /* tracks the address bar on mobile */
    margin: 0;
    padding: 0;
    overflow: hidden;
}

body {
    background: var(--bg-editor);
    color: var(--text);
    display: flex;
    flex-direction: column;
    font-family: var(--font-ui);
    font-size: 0.875rem;
    line-height: 1.5;
    -webkit-tap-highlight-color: transparent;
}

button, input, select, textarea { font: inherit; color: inherit; }
button { background: none; border: 0; cursor: pointer; }

:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

::-webkit-scrollbar { width: 0.5rem; height: 0.5rem; }
::-webkit-scrollbar-track { background: var(--bg-chrome); }
::-webkit-scrollbar-thumb { background: var(--bg-hover); }
::-webkit-scrollbar-thumb:hover { background: var(--text-muted); }

/* --------------------------------------------------------------------------
   3. Buttons and fields
   -------------------------------------------------------------------------- */

.btn {
    align-items: center;
    background: var(--bg-hover);
    border: 1px solid var(--border);
    color: var(--text);
    display: inline-flex;
    gap: 0.375rem;
    padding: 0.375rem 0.75rem;
    transition: background var(--duration), color var(--duration), border-color var(--duration);
    white-space: nowrap;
}
.btn:hover { border-color: var(--accent); color: var(--accent); }
.btn-primary { background: var(--accent); border-color: var(--accent); color: var(--bg-chrome); font-weight: 700; }
.btn-primary:hover { background: var(--accent-hover); border-color: var(--accent-hover); color: var(--bg-chrome); }
.btn-block { justify-content: center; margin-top: 0.75rem; width: 100%; }
.btn-icon { padding: 0.25rem 0.4rem; }
.btn svg { height: 1rem; width: 1rem; fill: currentColor; }

.field {
    background: var(--bg-chrome);
    border: 1px solid var(--border);
    color: var(--text);
    padding: 0.4rem 0.6rem;
    width: 100%;
}
.field:focus { border-color: var(--accent); outline: none; }
.field-narrow { width: auto; min-width: 8rem; }
.field-label { color: var(--text-muted); display: block; font-size: 0.75rem; margin-bottom: 0.25rem; }

.checkbox { align-items: center; color: var(--text-muted); display: inline-flex; gap: 0.25rem; }

.switch { display: inline-block; height: 1.25rem; position: relative; width: 2.5rem; flex: 0 0 auto; }
.switch input { height: 0; opacity: 0; width: 0; }
.switch-slider { background: var(--bg-hover); cursor: pointer; inset: 0; position: absolute; transition: background var(--duration); }
.switch-slider::before {
    background: var(--text-muted);
    content: "";
    height: 0.875rem;
    left: 0.1875rem;
    position: absolute;
    top: 0.1875rem;
    transition: transform var(--duration), background var(--duration);
    width: 0.875rem;
}
.switch input:checked + .switch-slider { background: var(--accent); }
.switch input:checked + .switch-slider::before { background: var(--bg-chrome); transform: translateX(1.125rem); }
.switch input:focus-visible + .switch-slider { outline: 2px solid var(--accent); outline-offset: 2px; }

/* --------------------------------------------------------------------------
   4. Topbar
   -------------------------------------------------------------------------- */

.topbar {
    align-items: center;
    background: var(--bg-chrome);
    border-bottom: 1px solid var(--bg-deep);
    display: flex;
    flex-shrink: 0;
    justify-content: space-between;
    padding: 0.25rem 0.5rem;
    user-select: none;
}

.topbar-left, .topbar-right { align-items: center; display: flex; gap: 0.25rem; min-width: 0; }

.brand {
    border-right: 1px solid var(--border);
    color: var(--accent);
    font-size: 0.875rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    margin: 0 0.5rem 0 0;
    padding: 0 0.75rem 0 0.25rem;
    white-space: nowrap;
}

.menu-trigger {
    color: var(--text);
    padding: 0.375rem 0.625rem;
    transition: background var(--duration);
}
.menu-trigger:hover, .menu-trigger[aria-expanded="true"] { background: var(--bg-hover); }

.menu-wrap { position: relative; }

.dropdown {
    background: var(--bg-editor);
    border: 1px solid var(--border);
    display: flex;
    flex-direction: column;
    left: 0;
    min-width: 15rem;
    padding: 0.25rem 0;
    position: absolute;
    top: 100%;
    z-index: 60;
}
.dropdown hr { border: 0; border-top: 1px solid var(--border); margin: 0.25rem 0; }

.dropdown-item {
    align-items: center;
    color: var(--text);
    display: flex;
    justify-content: space-between;
    padding: 0.4rem 0.875rem;
    text-align: left;
    width: 100%;
}
.dropdown-item:hover, .dropdown-item:focus { background: var(--bg-hover); outline: none; }
.dropdown-item kbd {
    color: var(--text-muted);
    font-family: var(--font-mono);
    font-size: 0.6875rem;
    padding-left: 1.5rem;
}

/* --------------------------------------------------------------------------
   5. Workspace: sidebar | editor | preview
   -------------------------------------------------------------------------- */

.workspace { display: flex; flex: 1; min-height: 0; overflow: hidden; }

.sidebar {
    background: var(--bg-chrome);
    border-right: 1px solid var(--bg-deep);
    display: none;
    flex: 0 0 var(--sidebar-width);
    flex-direction: column;
    min-width: 0;
    overflow: hidden;
}
body.sidebar-open .sidebar { display: flex; }

.sidebar-head {
    align-items: center;
    border-bottom: 1px solid var(--border);
    display: flex;
    gap: 0.25rem;
    justify-content: space-between;
    padding: 0.375rem 0.5rem;
}
.sidebar-title {
    color: var(--text-muted);
    font-size: 0.6875rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    overflow: hidden;
    text-overflow: ellipsis;
    text-transform: uppercase;
    white-space: nowrap;
}
.sidebar-actions { display: flex; flex: 0 0 auto; gap: 0.125rem; }
.sidebar-actions button {
    color: var(--text-muted);
    line-height: 1;
    padding: 0.25rem 0.375rem;
}
.sidebar-actions button:hover { background: var(--bg-hover); color: var(--accent); }

.sidebar-body { flex: 1; overflow-y: auto; padding: 0.5rem; }
.sidebar-empty { color: var(--text-muted); font-size: 0.8125rem; margin: 0.5rem 0; }

.tree-list { list-style: none; margin: 0; padding-left: 0.75rem; }
.sidebar-body > .tree-list { padding-left: 0; }

.tree-row {
    align-items: center;
    color: var(--text);
    display: flex;
    gap: 0.25rem;
    overflow: hidden;
    padding: 0.1875rem 0.25rem;
    text-align: left;
    width: 100%;
}
.tree-row:hover { background: var(--bg-hover); }
.tree-row.is-binary { color: var(--text-muted); }
.tree-icon { color: var(--text-muted); flex: 0 0 0.75rem; font-size: 0.625rem; }
.tree-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }


/* flex: 1 — not `flex: var(--editor-ratio) 1 0`, which was the bug: with flex-grow 0.55 and
   flex-basis 0, the editor took 55% of the free space and the other 45% stayed as a black
   gap when the preview was off. flex-grow below 1 doesn't fill the parent. */
.editor-pane {
    display: flex;
    flex: 1;
    flex-direction: column;
    min-width: 0;
}

.editor-host { flex: 1; position: relative; }
#editor { inset: 0; position: absolute; }

body.is-resizing iframe { pointer-events: none; }   /* o iframe engoliria o pointermove */

/* --------------------------------------------------------------------------
   6. Abas
   -------------------------------------------------------------------------- */

.tab-bar {
    background: var(--bg-chrome);
    border-bottom: 1px solid var(--bg-deep);
    display: flex;
    flex-shrink: 0;
    overflow-x: auto;
    scrollbar-width: none;
}
.tab-bar::-webkit-scrollbar { display: none; }

.tab {
    align-items: center;
    background: var(--bg-deep);
    border-right: 1px solid var(--bg-deep);
    border-top: 2px solid transparent;
    color: var(--text-muted);
    cursor: pointer;
    display: flex;
    flex: 0 0 auto;
    gap: 0.375rem;
    max-width: 14rem;
    padding: 0.375rem 0.5rem 0.375rem 0.75rem;
    transition: background var(--duration), color var(--duration);
    user-select: none;
}
.tab:hover { background: var(--bg-editor); color: var(--text); }
.tab.is-active { background: var(--bg-editor); border-top-color: var(--accent); color: var(--text); }
.tab.is-dragging { opacity: 0.4; }
.tab.is-drop-target { border-left: 2px solid var(--accent); }

.tab-dot { background: var(--warning); flex: 0 0 auto; height: 0.4375rem; width: 0.4375rem; }
.tab-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tab-rename {
    background: var(--bg-chrome);
    border: 1px solid var(--accent);
    color: var(--text);
    min-width: 6rem;
    padding: 0 0.25rem;
    width: 8rem;
}
.tab-close {
    color: var(--text-muted);
    flex: 0 0 auto;
    font-size: 1rem;
    line-height: 1;
    padding: 0 0.25rem;
}
.tab-close:hover { color: var(--danger); }

/* --------------------------------------------------------------------------
   7. Preview
   -------------------------------------------------------------------------- */


.preview-file {
    color: var(--text-muted);
    font-size: 0.75rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.preview-actions { display: flex; flex: 0 0 auto; gap: 0.125rem; }
.preview-actions button { color: var(--text-muted); padding: 0.25rem 0.375rem; }
.preview-actions button:hover { background: var(--bg-hover); color: var(--accent); }

.preview-body { background: #ffffff; flex: 1; min-height: 0; position: relative; }
.preview-frame { border: 0; height: 100%; width: 100%; }
.preview-scroll { height: 100%; overflow-y: auto; padding: 1.5rem; }
.preview-plain {
    background: var(--bg-editor);
    color: var(--text);
    font-family: var(--font-mono);
    font-size: 0.8125rem;
    height: 100%;
    margin: 0;
    overflow: auto;
    padding: 1rem;
    white-space: pre-wrap;
}

.preview-console {
    background: var(--bg-chrome);
    border-top: 1px solid var(--border);
    display: flex;
    flex-direction: column;
    flex-shrink: 0;
}
.console-head {
    align-items: center;
    display: flex;
    gap: 0.5rem;
    justify-content: space-between;
    padding: 0.25rem 0.5rem;
}
.console-title { color: var(--text-muted); font-size: 0.6875rem; letter-spacing: 0.06em; text-transform: uppercase; }
.console-count {
    background: var(--bg-hover);
    color: var(--text);
    font-size: 0.6875rem;
    padding: 0 0.375rem;
}
.console-list {
    display: none;
    font-family: var(--font-mono);
    font-size: 0.75rem;
    max-height: 10rem;
    overflow-y: auto;
    padding: 0.25rem 0.5rem;
}
.preview-console.is-open .console-list { display: block; }
.console-row { border-bottom: 1px solid var(--bg-deep); padding: 0.1875rem 0; white-space: pre-wrap; word-break: break-word; }
.console-log, .console-debug { color: var(--text); }
.console-info { color: var(--info); }
.console-warn { color: var(--warning); }
.console-error { color: var(--danger); }

/* --------------------------------------------------------------------------
   8. Status bar
   -------------------------------------------------------------------------- */

.statusbar {
    align-items: center;
    background: var(--bg-chrome);
    border-top: 1px solid var(--bg-deep);
    color: var(--text-muted);
    display: flex;
    flex-shrink: 0;
    font-size: 0.75rem;
    justify-content: space-between;
    padding: 0.25rem 0.625rem;
    padding-bottom: calc(0.25rem + var(--safe-bottom));
    position: sticky;
    bottom: 0;
    transform: translateY(calc(var(--keyboard-offset) * -1));
    transition: transform var(--duration) ease-out;
    user-select: none;
    z-index: 20;
}
.status-left, .status-right { align-items: center; display: flex; gap: 0.5rem; min-width: 0; }

.status-dot { flex: 0 0 auto; height: 0.5rem; width: 0.5rem; }
.status-dot.is-ok { background: var(--accent); }
.status-dot.is-pending { background: var(--warning); }
.status-dot.is-error { background: var(--danger); }

.status-btn {
    border: 1px solid transparent;
    color: var(--text-muted);
    padding: 0.0625rem 0.3125rem;
    transition: color var(--duration), border-color var(--duration);
    white-space: nowrap;
}
.status-btn:hover { border-color: var(--border); color: var(--accent); }
.status-btn.is-armed {
    animation: pulse 1.2s ease-in-out infinite;
    border-color: var(--accent);
    color: var(--accent);
}
@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.55; } }

.status-problems.has-errors { color: var(--danger); }
.status-problems.has-warnings { color: var(--warning); }

.status-chip { border: 1px solid var(--border); font-size: 0.6875rem; padding: 0 0.3125rem; }
.status-chip.is-linked { border-color: var(--accent); color: var(--accent); }

.status-cursor { font-family: var(--font-mono); font-size: 0.6875rem; }

/* Line-ending indicator (LF/CRLF) in the status bar. */
.status-eol {
    font-family: var(--font-mono);
    font-size: 0.6875rem;
    color: var(--text-muted);
    border: 1px solid var(--border);
    padding: 0 0.3125rem;
    border-radius: var(--radius);
}

/* --------------------------------------------------------------------------
   9. Modais
   -------------------------------------------------------------------------- */

.modal-root {
    align-items: center;
    background: rgba(0, 0, 0, 0.6);
    display: flex;
    inset: 0;
    justify-content: center;
    padding: 1rem;
    position: fixed;
    z-index: 100;
}

.modal {
    background: var(--bg-editor);
    border: 1px solid var(--border);
    display: flex;
    flex-direction: column;
    max-height: 90vh;
    max-width: 32rem;
    width: 100%;
}
.modal-wide { max-width: 44rem; }

.modal-head {
    align-items: center;
    border-bottom: 1px solid var(--border);
    display: flex;
    justify-content: space-between;
    padding: 0.75rem 1rem;
}
.modal-head h2 { color: var(--text-strong); font-size: 1rem; margin: 0; }
.modal-dismiss { color: var(--text-muted); padding: 0 0.25rem; }
.modal-dismiss:hover { color: var(--danger); }

.modal-body { overflow-y: auto; padding: 1rem; }
/* The preview is a flex column that must fill the height of the full modal.
   Without flex:1 + min-height:0 on the body, the iframe (height:100%) resolves to 0. */
.modal-full { display: flex; flex-direction: column; }
.modal-full .modal-body {
    display: flex;
    flex: 1;
    min-height: 0;
    padding: 0.5rem;
}
.modal-foot {
    border-top: 1px solid var(--border);
    display: flex;
    gap: 0.5rem;
    justify-content: flex-end;
    padding: 0.75rem 1rem;
}
.modal-text { margin: 0 0 0.75rem; }
.modal-hint { color: var(--text-muted); font-size: 0.75rem; margin: 0.75rem 0 0; }
.modal-links { margin: 1rem 0 0; }
.modal-links a { color: var(--accent); }

.setting-group { margin-bottom: 1.25rem; }
.setting-group h3 {
    color: var(--text-muted);
    font-size: 0.6875rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    margin: 0 0 0.5rem;
    text-transform: uppercase;
}
.setting-row {
    align-items: center;
    border-bottom: 1px solid var(--border);
    display: flex;
    gap: 1rem;
    justify-content: space-between;
    padding: 0.5rem 0;
}
.setting-row:last-child { border-bottom: 0; }
.setting-name { display: block; }
.setting-help { color: var(--text-muted); display: block; font-size: 0.75rem; }

.stats-grid { display: grid; gap: 0.5rem; grid-template-columns: 1fr 1fr; }
.stats-cell { background: var(--bg-chrome); border: 1px solid var(--border); padding: 0.5rem 0.625rem; }
.stats-cell strong { color: var(--text-strong); display: block; font-size: 1.125rem; }
.stats-cell span { color: var(--text-muted); font-size: 0.6875rem; letter-spacing: 0.05em; text-transform: uppercase; }

.lang-grid { display: grid; gap: 0.375rem; grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr)); margin-top: 0.75rem; max-height: 20rem; overflow-y: auto; }
.lang-option {
    align-items: center;
    background: var(--bg-chrome);
    border: 1px solid var(--border);
    color: var(--text);
    display: flex;
    justify-content: space-between;
    padding: 0.375rem 0.5rem;
    text-align: left;
}
.lang-option:hover { border-color: var(--accent); color: var(--accent); }
.lang-option.is-active { border-color: var(--accent); color: var(--accent); }
.lang-option-ext { color: var(--text-muted); font-family: var(--font-mono); font-size: 0.6875rem; }

.problem-list { display: flex; flex-direction: column; gap: 0.125rem; }
.problem-item {
    align-items: baseline;
    border-left: 2px solid var(--text-muted);
    color: var(--text);
    display: flex;
    gap: 0.625rem;
    padding: 0.375rem 0.5rem;
    text-align: left;
    width: 100%;
}
.problem-item:hover { background: var(--bg-hover); }
.problem-item.is-error { border-left-color: var(--danger); }
.problem-item.is-warning { border-left-color: var(--warning); }
.problem-item.is-info { border-left-color: var(--info); }
.problem-line { color: var(--text-muted); flex: 0 0 4rem; font-family: var(--font-mono); font-size: 0.75rem; }
.problem-text { word-break: break-word; }

.shortcut-group { border-top: 1px solid var(--border); padding: 0.5rem 0; }
.shortcut-group h3 {
    color: var(--text-muted);
    font-size: 0.6875rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    margin: 0 0 0.375rem;
    text-transform: uppercase;
}
.shortcut-row { display: grid; font-size: 0.8125rem; gap: 0.75rem; grid-template-columns: minmax(9rem, max-content) 1fr; padding: 0.125rem 0; }
.shortcut-row kbd {
    background: var(--bg-chrome);
    border: 1px solid var(--border);
    color: var(--accent);
    font-family: var(--font-mono);
    font-size: 0.6875rem;
    padding: 0.0625rem 0.3125rem;
    white-space: nowrap;
}

/* --------------------------------------------------------------------------
   10. Global search
   -------------------------------------------------------------------------- */

.search-panel { display: flex; flex-direction: column; gap: 0.5rem; }
.search-options { display: flex; flex-wrap: wrap; gap: 1rem; font-size: 0.8125rem; }
.search-summary { color: var(--text-muted); font-size: 0.75rem; margin: 0; }
.search-summary.is-error { color: var(--danger); }
.search-results { max-height: 24rem; overflow-y: auto; }
.search-group { margin-bottom: 0.75rem; }
.search-group-name { color: var(--accent); font-size: 0.75rem; font-weight: 700; padding: 0.25rem 0; }
.search-hit {
    align-items: baseline;
    color: var(--text);
    display: flex;
    font-family: var(--font-mono);
    font-size: 0.75rem;
    gap: 0.625rem;
    padding: 0.1875rem 0.375rem;
    text-align: left;
    width: 100%;
}
.search-hit:hover { background: var(--bg-hover); }
.search-line { color: var(--text-muted); flex: 0 0 2.5rem; text-align: right; }
.search-snippet { overflow: hidden; text-overflow: ellipsis; white-space: pre; }
.search-snippet mark { background: var(--accent); color: var(--bg-chrome); }

/* --------------------------------------------------------------------------
   11. Paleta de comandos
   -------------------------------------------------------------------------- */

.palette {
    background: rgba(0, 0, 0, 0.6);
    display: flex;
    inset: 0;
    justify-content: center;
    padding: 4rem 1rem 1rem;
    position: fixed;
    z-index: 110;
}
.palette[hidden] { display: none; }

.palette-panel {
    background: var(--bg-editor);
    border: 1px solid var(--border);
    display: flex;
    flex-direction: column;
    max-height: 60vh;
    max-width: 36rem;
    overflow: hidden;
    width: 100%;
}
.palette-input {
    background: var(--bg-chrome);
    border: 0;
    border-bottom: 1px solid var(--border);
    color: var(--text);
    padding: 0.75rem 1rem;
    width: 100%;
}
.palette-input:focus { border-bottom-color: var(--accent); outline: none; }
.palette-list { overflow-y: auto; }
.palette-item {
    align-items: center;
    color: var(--text);
    display: grid;
    font-size: 0.8125rem;
    gap: 0.625rem;
    grid-template-columns: 5.5rem 1fr max-content;
    padding: 0.5rem 1rem;
    text-align: left;
    width: 100%;
}
.palette-item:hover, .palette-item.is-active { background: var(--bg-hover); }
.palette-item.is-active .palette-title { color: var(--accent); }
.palette-group { color: var(--text-muted); font-size: 0.6875rem; letter-spacing: 0.05em; text-transform: uppercase; }
.palette-keys { color: var(--text-muted); font-family: var(--font-mono); font-size: 0.6875rem; }
.palette-empty { color: var(--text-muted); padding: 1.25rem 1rem; text-align: center; }

/* --------------------------------------------------------------------------
   11b. Mobile menu (bottom sheet)
   -------------------------------------------------------------------------- */

.mobile-menu {
    background: rgba(0, 0, 0, 0.5);
    display: flex;
    align-items: flex-end;
    inset: 0;
    position: fixed;
    z-index: 115;
}
.mobile-menu[hidden] { display: none; }

.mobile-menu-sheet {
    background: var(--bg-editor);
    border-top: 1px solid var(--border);
    border-radius: 0.75rem 0.75rem 0 0;
    display: flex;
    flex-direction: column;
    max-height: 85vh;
    width: 100%;
    overflow: hidden;
}

.mobile-menu-head {
    align-items: center;
    display: flex;
    gap: 0.5rem;
    padding: 0.5rem 1rem 0.375rem;
    border-bottom: 1px solid var(--border);
    flex-shrink: 0;
}

.mobile-menu-handle {
    width: 2.25rem;
    height: 0.25rem;
    border-radius: 0.25rem;
    background: var(--text-muted);
    opacity: 0.5;
    flex-shrink: 0;
}

.mobile-menu-title {
    flex: 1;
    font-size: 0.875rem;
    font-weight: 600;
    color: var(--text);
}

.mobile-menu-close {
    flex-shrink: 0;
    width: 2rem;
    height: 2rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: var(--text-muted);
    background: none;
    border: 0;
    cursor: pointer;
    border-radius: var(--radius);
    transition: background var(--duration), color var(--duration);
}
.mobile-menu-close:hover, .mobile-menu-close:focus-visible {
    background: var(--bg-hover);
    color: var(--text);
    outline: none;
}
.mobile-menu-close svg { width: 1.25rem; height: 1.25rem; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; }

.mobile-menu-body {
    overflow-y: auto;
    padding: 0.5rem 0.75rem calc(1rem + var(--safe-bottom, 0px));
    -webkit-overflow-scrolling: touch;
}

.mobile-menu-section {
    margin: 0.875rem 0 0.5rem;
    font-size: 0.6875rem;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--text-muted);
    padding-left: 0.25rem;
}
.mobile-menu-section:first-child { margin-top: 0.25rem; }

.mobile-menu-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(4.75rem, 1fr));
    gap: 0.5rem;
}

.mobile-menu-item {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.375rem;
    padding: 0.625rem 0.25rem;
    min-height: 4.5rem;
    background: var(--bg-chrome);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    color: var(--text);
    cursor: pointer;
    transition: background var(--duration), border-color var(--duration);
    text-align: center;
}
.mobile-menu-item:hover, .mobile-menu-item:focus-visible {
    background: var(--bg-hover);
    border-color: var(--accent);
    outline: none;
}
.mobile-menu-item:active { background: var(--bg-deep); }

.mobile-menu-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: var(--accent);
    flex-shrink: 0;
}
.mobile-menu-icon svg { width: 1.5rem; height: 1.5rem; }

.mobile-menu-label {
    font-size: 0.6875rem;
    line-height: 1.2;
    color: var(--text);
    word-break: break-word;
    hyphens: auto;
}

/* --------------------------------------------------------------------------
   12. Toasts, context menu, drop overlay
   -------------------------------------------------------------------------- */

.toast-stack {
    bottom: calc(2.5rem + var(--safe-bottom));
    display: flex;
    flex-direction: column;
    gap: 0.375rem;
    left: 50%;
    position: fixed;
    transform: translateX(-50%);
    width: min(24rem, calc(100vw - 2rem));
    z-index: 120;
}
.toast {
    align-items: center;
    animation: toast-in 0.18s ease-out;
    background: var(--bg-chrome);
    border: 1px solid var(--border);
    border-left: 3px solid var(--text-muted);
    display: flex;
    gap: 0.5rem;
    padding: 0.5rem 0.625rem;
}
.toast-out { opacity: 0; transition: opacity 0.18s; }
.toast-success { border-left-color: var(--accent); }
.toast-warn { border-left-color: var(--warning); }
.toast-error { border-left-color: var(--danger); }
.toast-text { flex: 1; font-size: 0.8125rem; }
.toast-action { color: var(--accent); font-weight: 700; white-space: nowrap; }
.toast-close { color: var(--text-muted); }
.toast-close:hover { color: var(--danger); }
@keyframes toast-in { from { opacity: 0; transform: translateY(0.5rem); } to { opacity: 1; transform: none; } }

.context-menu {
    background: var(--bg-editor);
    border: 1px solid var(--border);
    display: flex;
    flex-direction: column;
    min-width: 10rem;
    padding: 0.25rem 0;
    position: fixed;
    z-index: 130;
}
.context-menu-item { color: var(--text); padding: 0.375rem 0.75rem; text-align: left; }
.context-menu-item:hover { background: var(--bg-hover); }

.drop-overlay {
    align-items: center;
    background: rgba(0, 0, 0, 0.7);
    border: 2px dashed var(--accent);
    color: var(--accent);
    display: flex;
    font-size: 1.125rem;
    font-weight: 700;
    inset: 0;
    justify-content: center;
    pointer-events: none;
    position: fixed;
    z-index: 140;
}

/* --------------------------------------------------------------------------
   13. Markdown (preview)
   -------------------------------------------------------------------------- */

.markdown-body { color: #24292f; font-family: var(--font-ui); line-height: 1.7; max-width: 48rem; }
.markdown-body h1, .markdown-body h2, .markdown-body h3,
.markdown-body h4, .markdown-body h5, .markdown-body h6 { line-height: 1.3; margin: 1.5rem 0 0.75rem; }
.markdown-body h1 { border-bottom: 1px solid #d8dee4; font-size: 1.75rem; padding-bottom: 0.25rem; }
.markdown-body h2 { border-bottom: 1px solid #d8dee4; font-size: 1.375rem; padding-bottom: 0.25rem; }
.markdown-body h3 { font-size: 1.125rem; }
.markdown-body p { margin: 0 0 1rem; }
.markdown-body ul, .markdown-body ol { margin: 0 0 1rem; padding-left: 1.5rem; }
.markdown-body li { margin-bottom: 0.25rem; }
.markdown-body blockquote { border-left: 0.25rem solid #d8dee4; color: #57606a; margin: 0 0 1rem; padding: 0 1rem; }
.markdown-body code { background: #eff1f3; font-family: var(--font-mono); font-size: 0.85em; padding: 0.125rem 0.25rem; }
.markdown-body pre { background: #f6f8fa; margin: 0 0 1rem; overflow-x: auto; padding: 1rem; }
.markdown-body pre code { background: none; padding: 0; }
.markdown-body table { border-collapse: collapse; margin: 0 0 1rem; width: 100%; }
.markdown-body th, .markdown-body td { border: 1px solid #d8dee4; padding: 0.375rem 0.75rem; text-align: left; }
.markdown-body th { background: #f6f8fa; }
.markdown-body img { max-width: 100%; }
.markdown-body a { color: #0969da; }
.markdown-body hr { border: 0; border-top: 1px solid #d8dee4; margin: 1.5rem 0; }

/* --------------------------------------------------------------------------
   14. Symbol bar (mobile)
   -------------------------------------------------------------------------- */

.mobile-toolbar {
    background: var(--bg-chrome);
    border-top: 1px solid var(--border);
    bottom: calc(var(--keyboard-offset) + var(--statusbar-h, 2rem));
    display: none;
    left: 0;
    position: fixed;
    right: 0;
    z-index: 25;
}
.mobile-toolbar-inner {
    display: flex;
    gap: 0.25rem;
    overflow-x: auto;
    padding: 0.25rem 0.375rem;
    scrollbar-width: none;
}
.mobile-toolbar-inner::-webkit-scrollbar { display: none; }
/* 2.75rem = 44px, the smallest target a thumb hits reliably (WCAG 2.5.5 AAA,
   iOS HIG). The previous 36x32 was a visible source of mistyped symbols. */
.mobile-key {
    align-items: center;
    background: var(--bg-editor);
    border: 1px solid var(--border);
    color: var(--text);
    display: inline-flex;
    flex: 0 0 auto;
    font-family: var(--font-mono);
    justify-content: center;
    min-height: 2.75rem;
    min-width: 2.75rem;
    padding: 0.375rem 0.4375rem;
    user-select: none;
}
.mobile-key:active { background: var(--bg-hover); color: var(--accent); }

/* Action buttons (selection + clipboard) sit at the start of the bar and
   are visually distinct from the symbol keys: accent-tinted so users find
   them quickly, and the selection-mode toggle shows an active state. */
.mobile-action {
    background: var(--bg-chrome);
    color: var(--accent);
    font-family: var(--font-ui);
    font-size: 1rem;
    line-height: 1;
}
.mobile-action:active { background: var(--bg-hover); }
.mobile-action.is-active {
    background: var(--accent);
    border-color: var(--accent);
    color: #fff;
}
.mobile-sep {
    flex: 0 0 auto;
    width: 1px;
    align-self: stretch;
    margin: 0.125rem 0.1875rem;
    background: var(--border);
}

@media (max-width: 768px), (pointer: coarse) {
    .mobile-toolbar.is-visible { display: block; }
}

/* --------------------------------------------------------------------------
   15. Responsivo
   -------------------------------------------------------------------------- */



/* ── Project: badge, open dialog, context menu ───────────────────────────── */

/* The user needs to know whether they're editing the real files or a browser copy.
   Confusing the two costs lost work. */
.sidebar-badge {
    margin: 0;
    padding: 0.375rem 0.75rem;
    font-size: 0.6875rem;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--text-muted);
    background: var(--bg-chrome);
    border-bottom: 1px solid var(--border);
}

.project-options {
    display: flex;
    flex-direction: column;
    gap: 1.25rem;
}

.project-option h3 {
    margin: 0 0 0.25rem;
    font-size: 0.9375rem;
    font-weight: 600;
}

.project-option p {
    margin: 0 0 0.625rem;
    font-size: 0.8125rem;
    line-height: 1.5;
    color: var(--text-muted);
}

.project-option .btn:disabled {
    opacity: 0.45;
    cursor: not-allowed;
}

.context-menu {
    position: fixed;
    z-index: 60;
    min-width: 10rem;
    padding: 0.25rem 0;
    background: var(--bg-chrome);
    border: 1px solid var(--border);
    box-shadow: none;
}

.context-item {
    display: block;
    width: 100%;
    padding: 0.5rem 0.875rem;
    font: inherit;
    font-size: 0.8125rem;
    text-align: left;
    color: var(--text);
    background: none;
    border: 0;
    cursor: pointer;
}

.context-item:hover,
.context-item:focus-visible {
    background: var(--bg-hover);
}

.context-item.is-danger { color: var(--danger); }

.tree-row.is-selected {
    background: var(--bg-hover);
}

.btn-danger {
    color: #fff;
    background: var(--danger);
    border-color: var(--danger);
}

.search-scope {
    margin-bottom: 0.75rem;
}

.search-scope .field {
    width: 100%;
}

/* ══ Editor themes ══════════════════════════════════════════════════════════
   Themes are pure CSS: switching themes is switching a class on the editor
   container. The colors live here, alongside the rest of the visual system. */

.tc-tabcode-dark,
.tc-tabcode-light,
.tc-tabcode-contrast {
    background: var(--bg-editor);
    color: var(--text);
}

.tc-tabcode-light { --bg-editor: #fbfbfa; --text: #22221f; }
.tc-tabcode-contrast { --bg-editor: #000; --text: #fff; }

/* ══ Built-in editor ══════════════════════════════════════════════════════ */

.tc-editor {
    position: relative;
    width: 100%;
    height: 100%;
    overflow: hidden;
    font-family: 'JetBrains Mono', Menlo, Monaco, Consolas, 'Courier New', monospace;
    background: var(--bg-editor);
    color: var(--text);
    line-height: 20px; /* fallback; overridden inline by the renderer */
    tab-size: 4;
    -moz-tab-size: 4;
}

.tc-gutter {
    position: absolute;
    top: 0;
    left: 0;
    width: 48px;
    height: 100%;
    overflow: hidden;
    background: var(--bg-chrome);
    color: var(--text-muted);
    user-select: none;
    text-align: right;
    z-index: 3;
}

.tc-gutter-cell,
.tc-gutter-line {
    padding: 0 8px 0 0;
    box-sizing: border-box;
}

.tc-scroller {
    position: absolute;
    top: 0;
    left: 48px;
    right: 0;
    bottom: 0;
    overflow: auto;
    z-index: 2;
}

/* When the minimap is visible, the scroller leaves room for it on the right. */
.tc-minimap:not([hidden]) ~ .tc-scroller,
.tc-editor:has(.tc-minimap:not([hidden])) .tc-scroller {
    right: 60px;
}

.tc-minimap {
    position: absolute;
    top: 0;
    right: 0;
    width: 60px;
    height: 100%;
    background: var(--bg-chrome);
    border-left: 1px solid var(--border);
    z-index: 3;
    cursor: pointer;
    image-rendering: pixelated;
}
.tc-minimap[hidden] { display: none; }

.tc-sizer {
    position: relative;
    min-width: 100%;
    min-height: 100%;
}

.tc-lines {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    z-index: 2;
}

.tc-line {
    white-space: pre;
    height: 20px; /* fallback; overridden inline by the renderer */
    padding: 0 4px;
    box-sizing: border-box;
}

.tc-line.is-active { background: rgba(255, 255, 255, 0.04); }
.tc-tabcode-light .tc-line.is-active { background: rgba(0, 0, 0, 0.04); }

/* The rendered lines are never selectable by the browser, on any device. They
   are a painting of the document; selection lives in the editor's own model
   and is drawn by .tc-selection-rect. On touch this also matters for input:
   a selectable line competes with the overlay textarea for the same gesture,
   which is what kept the virtual keyboard from opening. */
@media (pointer: coarse) {
    .tc-line,
    .tc-line * {
        -webkit-user-select: none;
        user-select: none;
        -webkit-touch-callout: none;
    }
}

.tc-selection {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    z-index: 1;
    pointer-events: none;
}

.tc-selection-rect {
    position: absolute;
    background: #49483e;
}
.tc-tabcode-light .tc-selection-rect { background: #d6d6cf; }
.tc-tabcode-contrast .tc-selection-rect { background: #0050c8; }

.tc-cursor {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    z-index: 3;
    pointer-events: none;
}

.tc-cursor-rect {
    position: absolute;
    width: 1px;
    background: var(--text);
    animation: tc-blink 1s steps(1) infinite;
}

@keyframes tc-blink {
    0%, 50% { opacity: 1; }
    50.01%, 100% { opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
    .tc-cursor-rect { animation: none; }
}

.tc-textarea {
    position: absolute;
    top: 0;
    left: 0;
    width: 1px;
    height: 20px; /* fallback; overridden inline by the renderer */
    margin: 0;
    padding: 0;
    border: 0;
    /* opacity:0 makes iOS Safari treat the textarea as "invisible" and refuse
       to open the virtual keyboard on focus(). 0.01 is visually imperceptible
       but counts as visible for focus/keyboard purposes. */
    opacity: 0.01;
    resize: none;
    background: transparent;
    color: transparent;
    caret-color: transparent;
    z-index: 0;
    overflow: hidden;
    font-family: inherit;
    font-size: inherit;
    line-height: inherit;
}

/* On touch the textarea stops being a 1px hiding spot and becomes a
   transparent overlay across the whole scroller, above the rendered lines.
   The tap then lands on a real editable element and the browser raises the
   virtual keyboard on its own — no programmatic focus() inside a gesture, the
   part that fails on iOS Safari and Chrome Android. `pan-x pan-y` classifies a
   drag as a scroll of the ancestor, so the overlay never blocks scrolling; the
   textarea is emptied on every input event, so it has no scroll of its own to
   swallow the gesture. Input, JS-driven, is bound in input.js (_bindTouch). */
@media (pointer: coarse) {
    .tc-textarea {
        /* Starting size only — the renderer keeps the overlay aligned with the
           viewport on every scroll and repaint (_syncTouchOverlay). */
        width: 100%;
        height: 100%;
        z-index: 4; /* above .tc-lines (2) and .tc-cursor (3) */
        touch-action: pan-x pan-y;
    }
}

/* iOS Safari auto-zooms the page when focusing an input with font-size <16px.
   The textarea is invisible, so forcing 16px on touch devices avoids the zoom
   without affecting the rendered text (which lives in the lines layer). */
@media (pointer: coarse) {
    .tc-textarea { font-size: 16px; }
}

.tc-invisible { color: var(--text-muted); }

/* Token colors */
.tok-comment { color: #75715e; font-style: italic; }
.tok-keyword { color: #f92672; }
.tok-string { color: #e6db74; }
.tok-number,
.tok-constant { color: #ae81ff; }
.tok-type { color: #66d9ef; font-style: italic; }
.tok-function { color: #a6e22e; }
.tok-variable { color: #fd971f; }
.tok-attribute { color: #a6e22e; }
.tok-punctuation,
.tok-operator { color: #f8f8f2; }
.tok-identifier { color: var(--text); }
.tok-regexp { color: #e6db74; }
.tok-tag { color: #f92672; }

.tc-tabcode-light .tok-comment { color: #8a8a7a; }
.tc-tabcode-light .tok-keyword { color: #c4157a; }
.tc-tabcode-light .tok-constant { color: #7a3fc0; }
.tc-tabcode-light .tok-string { color: #8a6a00; }
.tc-tabcode-light .tok-function,
.tc-tabcode-light .tok-attribute { color: #4a7c00; }
.tc-tabcode-light .tok-type { color: #0a6f85; }
.tc-tabcode-light .tok-variable { color: #a35200; }
.tc-tabcode-light .tok-punctuation,
.tc-tabcode-light .tok-operator { color: #22221f; }

.tc-tabcode-contrast .tok-comment { color: #9de89d; font-style: normal; }
.tc-tabcode-contrast .tok-keyword,
.tc-tabcode-contrast .tok-tag { color: #ff7ab2; }
.tc-tabcode-contrast .tok-constant { color: #d4b8ff; }
.tc-tabcode-contrast .tok-string { color: #ffe066; }
.tc-tabcode-contrast .tok-function { color: #b8ff5c; }
.tc-tabcode-contrast .tok-type { color: #7ce8ff; }
.tc-tabcode-contrast .tok-variable { color: #ffb055; }
.tc-tabcode-contrast .tok-punctuation,
.tc-tabcode-contrast .tok-operator { color: #fff; }

/* ══ Autocomplete ══════════════════════════════════════════════════════════ */

.autocomplete {
    position: fixed;
    z-index: 55;
    max-height: 13rem;
    min-width: 10rem;
    margin: 0;
    padding: 0;
    overflow-y: auto;
    list-style: none;
    background: var(--bg-chrome);
    border: 1px solid var(--border);
}

.autocomplete-item {
    padding: 0.25rem 0.75rem;
    font-family: var(--font-mono);
    font-size: 0.8125rem;
    color: var(--text);
    cursor: pointer;
}

.autocomplete-item.is-selected,
.autocomplete-item:hover { background: var(--bg-hover); }

/* ══ In-file search bar ════════════════════════════════════════════════════ */

.findbar {
    display: none;
    padding: 0.5rem;
    background: var(--bg-chrome);
    border-bottom: 1px solid var(--border);
}

.findbar.is-open { display: block; }
.findbar:not(.show-replace) .findbar-row:nth-child(2) { display: none; }

.findbar-row {
    display: flex;
    gap: 0.375rem;
    align-items: center;
    margin-bottom: 0.375rem;
}

.findbar-row .field { flex: 1; min-width: 0; }

.findbar-count {
    flex-shrink: 0;
    min-width: 4.5rem;
    font-size: 0.75rem;
    text-align: right;
    color: var(--text-muted);
}

.findbar-count.is-error { color: var(--danger); }

.findbar-btn {
    flex-shrink: 0;
    width: 1.75rem;
    height: 1.75rem;
    font-size: 0.75rem;
    color: var(--text);
    background: none;
    border: 1px solid var(--border);
    cursor: pointer;
}

.findbar-btn:hover,
.findbar-btn:focus-visible { background: var(--bg-hover); }

.findbar-options {
    display: flex;
    gap: 0.75rem;
}

.findbar-toggle {
    display: flex;
    gap: 0.25rem;
    align-items: center;
    font-family: var(--font-mono);
    font-size: 0.75rem;
    color: var(--text-muted);
    cursor: pointer;
}

/* ══ Diff (AI response review) ═════════════════════════════════════════════ */

.diff {
    max-height: 22rem;
    overflow: auto;
    font-family: var(--font-mono);
    font-size: 0.75rem;
    line-height: 1.6;
    background: var(--bg-deep);
    border: 1px solid var(--border);
}

.diff-line { display: flex; white-space: pre; }
.diff-sign {
    flex-shrink: 0;
    width: 1.25rem;
    text-align: center;
    color: var(--text-muted);
    user-select: none;
}
.diff-text { flex: 1; padding-right: 0.5rem; }

.diff-line.is-add { background: rgba(166, 226, 46, 0.12); }
.diff-line.is-add .diff-sign { color: var(--accent); }
.diff-line.is-remove { background: rgba(249, 38, 114, 0.12); }
.diff-line.is-remove .diff-sign { color: var(--danger); }
.diff-line.is-gap {
    justify-content: center;
    color: var(--text-muted);
    background: var(--bg-chrome);
}

.diff-note,
.diff-raw {
    margin: 0;
    padding: 0.75rem;
    font-size: 0.75rem;
    color: var(--text-muted);
}
.diff-raw {
    max-height: 18rem;
    overflow: auto;
    font-family: var(--font-mono);
    color: var(--text);
    white-space: pre-wrap;
}

/* ══ IA ════════════════════════════════════════════════════════════════════ */

.ai-settings,
.ai-panel { display: flex; flex-direction: column; gap: 0.875rem; }

.ai-warning {
    margin: 0;
    padding: 0.625rem 0.75rem;
    font-size: 0.75rem;
    line-height: 1.5;
    color: var(--warning);
    background: rgba(230, 219, 116, 0.1);
    border-left: 3px solid var(--warning);
}

.ai-responsibility {
    margin-top: 0.5rem;
    color: var(--text-muted);
    background: rgba(127, 127, 127, 0.08);
    border-left-color: var(--text-muted);
}

.ai-context {
    margin: 0;
    font-family: var(--font-mono);
    font-size: 0.75rem;
    color: var(--text-muted);
}

.ai-actions { display: flex; flex-wrap: wrap; gap: 0.375rem; }

.ai-status {
    margin: 0;
    min-height: 1.25rem;
    font-size: 0.8125rem;
    color: var(--text-muted);
}
.ai-status.is-ok { color: var(--accent); }
.ai-status.is-error { color: var(--danger); }

.ai-stream {
    max-height: 22rem;
    margin: 0;
    padding: 0.75rem;
    overflow: auto;
    font-family: var(--font-mono);
    font-size: 0.75rem;
    line-height: 1.6;
    white-space: pre-wrap;
    background: var(--bg-deep);
    border: 1px solid var(--border);
}

.ai-reveal { align-self: flex-start; margin-top: 0.375rem; }

.field-group { display: flex; flex-direction: column; gap: 0.25rem; }
.field-textarea {
    font-family: var(--font-mono);
    font-size: 0.8125rem;
    line-height: 1.5;
    resize: vertical;
}

.btn-small {
    padding: 0.25rem 0.625rem;
    font-size: 0.75rem;
}

.btn:disabled { opacity: 0.4; cursor: not-allowed; }

/* ══ Accessibility ═══════════════════════════════════════════════════════ */

/* First Tab target. Stays off-screen until focused — mouse users never see it,
   keyboard users don't walk through 20 buttons to reach the editor. */
.skip-link {
    position: absolute;
    top: -3rem;
    left: 0.5rem;
    z-index: 100;
    padding: 0.5rem 0.875rem;
    font-size: 0.8125rem;
    color: var(--bg-deep);
    background: var(--accent);
    transition: top var(--duration);
}

.skip-link:focus {
    top: 0.5rem;
}

/* System high-contrast mode (Windows). In this mode the OS ignores our colors;
   what must not happen is the focus outline disappearing along with them. */
@media (forced-colors: active) {
    .btn,
    .tab,
    .tree-row,
    .dropdown-item,
    .findbar-btn {
        border: 1px solid ButtonBorder;
    }

    :focus-visible {
        outline: 2px solid Highlight;
        outline-offset: 2px;
    }

    .tab.is-active,
    .tree-row.is-selected,
    .autocomplete-item.is-selected {
        background: Highlight;
        color: HighlightText;
        forced-color-adjust: none;
    }

    /* The "modified" dot is just color: without forcing, it disappears. */
    .tab-dot {
        forced-color-adjust: none;
        background: Highlight;
    }
}

/* Touch targets: 24px is the WCAG 2.2 minimum (2.5.8). The tree and search bar
   icons were below that on mobile. */
@media (pointer: coarse) {
    .findbar-btn,
    .tree-row,
    .context-item,
    .autocomplete-item {
        min-height: 2.75rem;
    }

    .findbar-btn {
        min-width: 2.75rem;
    }
}

.ai-output:empty { display: none; }
.tree-item { margin: 0; }

/* ══ Preview (modal) ═══════════════════════════════════════════════════════
   Era um split. O split reservava metade da largura mesmo desligado e, num celular,
   dava 190px para cada lado — largura em que nem o editor nem o preview servem. */

.modal-full {
    width: 100%;
    max-width: 68rem;
    height: 100%;
    max-height: 92vh;
}

.preview {
    display: flex;
    flex: 1;
    flex-direction: column;
    min-height: 0;
}

.preview-bar {
    display: flex;
    flex-shrink: 0;
    gap: 0.375rem;
    align-items: center;
    padding-bottom: 0.5rem;
    border-bottom: 1px solid var(--border);
}

.preview-file {
    font-family: var(--font-mono);
    font-size: 0.75rem;
    color: var(--text-muted);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.preview-spacer { flex: 1; }

.preview-body {
    flex: 1;
    min-height: 0;
    background: #fff;   /* the preview is a page: white background, not the editor theme */
}

.preview-frame {
    width: 100%;
    height: 100%;
    border: 0;
}

.preview-scroll {
    height: 100%;
    margin: 0;
    padding: 1rem;
    overflow: auto;
    /* Inherits the white page background from .preview-body */
}

.preview-plain {
    height: 100%;
    margin: 0;
    padding: 1rem;
    overflow: auto;
    background: var(--bg-editor);
    color: var(--text);
    font-family: var(--font-mono);
    font-size: 0.8125rem;
    white-space: pre-wrap;
}

.preview-console {
    position: relative;
    flex-shrink: 0;
    height: 9rem;
    border-top: 1px solid var(--border);
}

.preview-console-clear {
    position: absolute;
    top: 0.25rem;
    right: 0.25rem;
}

.console-list {
    height: 100%;
    padding: 0.5rem;
    overflow: auto;
    font-family: var(--font-mono);
    font-size: 0.75rem;
    line-height: 1.6;
    background: var(--bg-deep);
}

.console-row { white-space: pre-wrap; word-break: break-word; }
.console-warn { color: var(--warning); }
.console-error { color: var(--danger); }
.console-info { color: var(--info); }

/* ══ Responsive ═════════════════════════════════════════════════════════════
   TabCode is a mobile editor that also runs on desktop, not the other way around.
   Three decisions guide everything here:

   1. No horizontal scroll. Ever. An editor that sways sideways on touch is
      unusable — and the gesture to scroll code competes with scrolling the page.
   2. Five dropdowns don't fit in 380px. Instead of squeezing them, we collapse them
      into the command palette, which already exists, groups everything and is searchable.
   3. The sidebar covers the editor on mobile, so it needs a way to close that isn't
      "find the button underneath it". */

html, body {
    overflow-x: hidden;
    overscroll-behavior: none;   /* no pull-to-refresh dropping what you're typing */
}

.mobile-only { display: none; }

.sidebar-backdrop {
    position: fixed;
    inset: 0;
    z-index: 45;
    background: rgba(0, 0, 0, 0.5);
}

@media (min-width: 901px) {
    .sidebar-backdrop { display: none !important; }
}

/* ── Tablet and below ─────────────────────────────────────────────────────── */

@media (max-width: 900px) {
    /* No width to split: the sidebar leaves the flow and overlays. */
    .sidebar {
        position: fixed;
        top: 0;
        bottom: 0;
        left: 0;
        z-index: 50;
        /* explicit width: in position:fixed flex-basis doesn't apply, and the sidebar
           collapsed to its content. */
        width: min(85vw, 20rem);
        border-right: 1px solid var(--border);
    }

    body.sidebar-open .sidebar { display: flex; }
}

/* ── Mobile ──────────────────────────────────────────────────────────────── */

@media (max-width: 640px) {
    .brand { display: none; }
    .btn-label { display: none; }
    .btn { padding: 0.375rem 0.5rem; }

    /* The five menus become one: the palette. */
    .menu-wrap { display: none; }
    .mobile-only { display: inline-flex; }

    .topbar {
        padding-left: 0.25rem;
        padding-right: 0.25rem;
        gap: 0.25rem;
    }

    /* Modal takes the full screen. A 60% dialog on mobile leaves 40% of useless
       background and pushes action buttons out of thumb reach. */
    .modal,
    .modal-wide,
    .modal-full {
        width: 100%;
        max-width: 100%;
        height: 100%;
        max-height: 100%;
        border: 0;
    }

    .modal-root { padding: 0; }

    /* Modal actions stacked and full-width: large target, reachable with the thumb. */
    .modal-foot {
        flex-direction: column-reverse;
        gap: 0.375rem;
        padding-bottom: calc(0.75rem + var(--safe-bottom));
    }
    .modal-foot .btn { width: 100%; justify-content: center; }

    .shortcut-row { grid-template-columns: 1fr; gap: 0.125rem; }
    .stats-grid { grid-template-columns: 1fr; }
    .status-cursor, .status-chars, .status-eol { display: none; }

    /* The preview console eats half of a small screen. */
    .preview-console { height: 7rem; }

    /* The search bar wraps to two rows instead of squeezing everything into one. */
    .findbar-row { flex-wrap: wrap; }
    .findbar-row .field { flex: 1 0 100%; }

    /* The autocomplete popup can't overflow the screen or cover what's being typed. */
    .autocomplete {
        max-width: calc(100vw - 1rem);
        max-height: 9rem;
    }

    /* Open project dialog: the three options stacked with breathing room. */
    .project-options { gap: 1.5rem; }
}

/* ── Touch ────────────────────────────────────────────────────────────────── */

@media (pointer: coarse) {
    /* WebKit's gray tap-flash makes the UI feel frozen. */
    * { -webkit-tap-highlight-color: transparent; }

    /* Larger tabs without breaking the horizontal scroll gesture. */
    .tab {
        min-height: 2.75rem;
        padding-right: 0.5rem;
    }
    .tab-close {
        width: 2rem;
        height: 2rem;
    }

    .dropdown-item,
    .status-btn,
    .modal-dismiss {
        min-height: 2.75rem;
    }

    /* Tab drag-reorder conflicts with the bar's horizontal scroll on touch.
       The context menu (long press) keeps moving — without hijacking the scroll. */
    .tab { touch-action: pan-x; }
}
