/*--------------------------------------------------------------
# generate-update-sql-v2.html — fully isolated stylesheet.
# Not referenced by any production page. Reuses the TableToSQL
# palette (dark navy header, green SET, and a blue WHERE to match
# it) but every selector here is scoped to this prototype only.
--------------------------------------------------------------*/

:root {
    --v2-navy: #07143d;
    --v2-heading: #040677;
    --v2-text: #333333;
    --v2-muted: #6b7280;
    --v2-border: #e2e5ec;
    --v2-bg: #f5f7fb;
    --v2-green: #16a34a;
    --v2-green-bg: #e8fff2;
    --v2-blue: #2563eb;
    --v2-blue-bg: #eaf1ff;
}

.v2-page {
    background: var(--v2-bg);
    color: var(--v2-text);
    font-family: "Roboto", system-ui, sans-serif;
    /* Defensive only: nothing here is currently known to overflow, but a
       full-page horizontal scrollbar is explicitly out of bounds for the
       phone layout below, so this is a backstop rather than a fix for a
       known bug. */
    overflow-x: hidden;
    /* The shared production header (includes/header.html) is
       position:fixed (main.css's .header + the fixed-top class) -- it
       doesn't occupy normal flow, so without this the page's own content
       renders underneath it instead of below it. Production's other pages
       never needed this because their hero sections happen to carry enough
       of their own top padding to clear it; this page has no such hero.
       Matches the header's own measured height at each of its two nav
       modes (68px row; see includes/header.html + its site.css rules)
       rather than an arbitrary guess. */
    padding-top: 68px;
}

@media (max-width: 991.98px) {
    .v2-page {
        /* Header is taller here: the page subtitle stacks under the brand
           on its own line on phones (measured ~67px total). */
        padding-top: 68px;
    }
}

/* ---------------- Topbar ---------------- */
.v2-topbar {
    background: var(--v2-navy);
    padding: 14px 0;
}

.v2-topbar-inner {
    max-width: 1400px;
    margin: 0 auto;
    padding: 0 24px;
    display: flex;
    align-items: center;
    gap: 16px;
    flex-wrap: wrap;
}

.v2-logo {
    color: #ffffff;
    font-weight: 700;
    font-size: 20px;
    text-decoration: none;
}

/* Compact page title, moved into the topbar (instead of a standalone h1 +
   subtitle block in the body) to reclaim vertical space -- the topbar's own
   height is unaffected, so this must stay a single line at the topbar's
   font scale rather than a bigger heading. */
.v2-topbar-title {
    margin-left: auto;
    color: #ffffff;
    font-size: 15px;
    font-weight: 600;
    white-space: nowrap;
}

.v2-topbar-title strong {
    color: #21e39b;
    font-weight: 700;
}

.v2-main {
    max-width: 1400px;
    margin: 0 auto;
    padding: 28px 24px 60px;
}

/* Compact page H1, shown above the generator on each individual
   generate-*.html page (page content, not part of the shared
   includes/script.html generator -- see that file's own comment on why
   hero/H1 content stays out of it). Deliberately its own color (not
   var(--v2-heading), #040677 -- close but not the same shade) and a lighter
   weight than this page's H2s (.v2-section-title, .v2-value-section h2),
   so it reads as a compact page title rather than a hero heading.
   640px matches the same phone breakpoint already used throughout this
   file (see the "Phone-only acquisition blocks" section below). */
.v2-page-h1 {
    font-size: 32px;
    font-weight: 600;
    line-height: 1.2;
    margin: 0 0 14px;
    color: #0b1680;
}

@media (max-width: 640px) {
    .v2-page-h1 {
        font-size: 24px;
    }
}

/* ---------------- Layout ---------------- */
/* ~60% / 40%: left = data + SQL result, right = query configuration. */
.v2-layout {
    display: grid;
    grid-template-columns: minmax(0, 3fr) minmax(0, 2fr);
    gap: 20px;
    align-items: start;
}

.v2-left, .v2-right {
    display: flex;
    flex-direction: column;
    gap: 12px;
    min-width: 0;
}

.v2-card {
    background: #ffffff;
    border: 1px solid var(--v2-border);
    border-radius: 12px;
    padding: 18px;
}

/* Denser than the default .v2-card padding: this card is just a row of
   buttons, not content that needs breathing room. */
.v2-actions-card {
    padding-top: 13px;
    padding-bottom: 13px;
}

/* ---------------- Action buttons ---------------- */
.v2-action-buttons {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 10px;
}

.v2-btn {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    border-radius: 8px;
    padding: 10px 16px;
    font-size: 14px;
    font-weight: 600;
    border: 1px solid transparent;
    cursor: pointer;
    transition: all 0.15s ease;
    background: #ffffff;
}

.v2-btn-outline {
    border-color: var(--v2-border);
    color: var(--v2-text);
}

.v2-btn-outline:hover {
    border-color: var(--v2-blue);
    color: var(--v2-blue);
    /* Explicit override: site.css (shared with production, not touched here)
       has a generic `button:hover { background: #005fa3 }` rule for its own
       modal buttons that otherwise leaks onto every <button> on the page,
       including these -- a dark blue background under this rule's blue text
       was nearly unreadable. */
    background: #ffffff;
}

.v2-btn-danger-outline {
    border-color: #fecaca;
    color: #dc2626;
}

.v2-btn-danger-outline:hover {
    background: #fef2f2;
}

/* Upload Excel / Paste Table: solid-color primary actions, visually
   distinct from Example Data (stays .v2-btn-outline, secondary/white) and
   Clear Data (stays .v2-btn-danger-outline, white with red border/text).
   Scoped by id, not a shared class, since #btnLoadExcel/#btnPaste/
   #btnPasteExample all currently share .v2-btn-outline and only the first
   two should change -- this lives in includes/script.html's shared
   generator markup, so it applies to every page that fetches it. Icon
   color isn't set separately: the <i> inside each button inherits `color`
   from it, same as .v2-btn-primary/.v2-btn-danger-outline already do. */
#btnLoadExcel {
    background: var(--v2-green);
    border-color: var(--v2-green);
    color: #ffffff;
}

#btnLoadExcel:hover {
    background: #15803d;
    border-color: #15803d;
    color: #ffffff;
}

#btnPaste {
    background: var(--v2-blue);
    border-color: var(--v2-blue);
    color: #ffffff;
}

#btnPaste:hover {
    background: #1d4ed8;
    border-color: #1d4ed8;
    color: #ffffff;
}

.v2-btn-primary {
    background: var(--v2-blue);
    color: #ffffff;
}

.v2-btn-primary:hover {
    background: #1d4ed8;
}

.v2-btn-secondary {
    background: #ffffff;
    border-color: var(--v2-border);
    color: var(--v2-text);
}

.v2-btn-secondary:hover {
    border-color: var(--v2-blue);
    color: var(--v2-blue);
    /* See the matching comment on .v2-btn-outline:hover above. */
    background: #ffffff;
}

.v2-btn:disabled {
    opacity: 0.45;
    cursor: not-allowed;
}

.v2-btn-secondary:disabled:hover {
    border-color: var(--v2-border);
    color: var(--v2-text);
}

.v2-progress {
    position: relative;
    margin-top: 10px;
    /* Tall enough for the percentage label below -- 8px clipped it
       vertically since Bootstrap's .progress-bar normally centers text at a
       ~12-13px line-height. */
    height: 20px;
    width: 220px;
    /* Sits inside .v2-loading-overlay's column flex layout, which was
       tight enough (spinner + text + this bar + gaps + padding, against
       .v2-table-card's 120px min-height) that the default flex-shrink:1
       squeezed this down well below 20px, clipping the label above it was
       supposed to fix. */
    flex-shrink: 0;
}

/* updateProgress() (reused, unmodified) sets #progress-bar's own width AND
   writes "NN%" as that same element's text -- fine at high percentages, but
   at low ones the fill is far narrower than the text, so the text overflows
   and gets clipped by .progress's rounded-corner overflow:hidden. Hiding
   that native text and mirroring it in a separately-positioned label (see
   the updateProgress() wrap in home-v2.js) keeps it centered across the
   bar's full width regardless of how narrow the fill itself is. */
#progress-bar {
    color: transparent;
    /* Bootstrap animates .progress-bar's width over 0.6s. That was
       invisible before -- the percentage text lived inside this same
       animating element, so the number and the fill's edge always moved
       together. Now that the number lives in a separate, non-animated
       label, the two would drift apart on fast updates (label already at
       97% while the fill visually is still catching up from a much lower
       value) unless this element's own width changes are instant too. */
    transition: none;
}

.v2-progress-label {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    /* Explicit, not inherited: a browser/Bootstrap default line-height
       taller than this bar is centered by the flex rules below same as the
       text itself, so it still overflows .v2-progress's overflow:hidden
       and clips the glyphs top and bottom. */
    line-height: 1;
    font-size: 11px;
    font-weight: 700;
    color: var(--v2-heading);
    pointer-events: none;
}

/* ---------------- Sheets / Tables nav ---------------- */
.v2-tabs-row {
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
    margin-bottom: 10px;
}

.v2-tabs-row:last-of-type {
    margin-bottom: 0;
}

.v2-tabs-label {
    font-size: 12px;
    font-weight: 700;
    letter-spacing: 0.04em;
    color: var(--v2-muted);
    white-space: nowrap;
}

.v2-tabs {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

.v2-tab {
    border: 1px solid var(--v2-border);
    background: #f3f4f8;
    color: var(--v2-text);
    border-radius: 999px;
    padding: 6px 14px;
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
}

.v2-tab.active {
    background: var(--v2-blue);
    border-color: var(--v2-blue);
    color: #ffffff;
}

.v2-total-records {
    display: block;
    margin-left: auto;
    font-size: 12px;
    color: var(--v2-muted);
    font-weight: 600;
}

/* ---------------- Configure Columns band ---------------- */
.v2-section-title {
    font-size: 15px;
    font-weight: 700;
    color: var(--v2-heading);
    margin: 0 0 10px;
}

.v2-section-hint {
    font-size: 12px;
    font-weight: 400;
    color: var(--v2-muted);
}

.v2-config-band {
    overflow: hidden;
    position: relative;
}

.v2-config-band-inner {
    display: flex;
    align-items: stretch;
    gap: 0;
    /* padding-left is set inline by v2SyncBandWidths(), measured live
       against the grid's first data cell so it always matches exactly. */
    will-change: transform;
}

.v2-col-card {
    position: relative;
    flex: 0 0 auto;
    box-sizing: border-box;
    /* Right-edge-only border, same convention Handsontable itself uses for
       cell borders, so widths measured from <td> transfer over exactly
       instead of drifting from mismatched left/right borders. */
    border-right: 1px solid var(--v2-border);
    padding: 10px 8px;
    display: flex;
    flex-direction: column;
    gap: 6px;
    background: #fafbfe;
}

/* Mirrors the whole-column selection made by clicking the name area (or the
   grid itself) -- production's Handsontable column headers (A/B/C…) show this
   natively; V2 has no visible column headers, so the card takes over. */
.v2-col-card.selected {
    background: #eef2ff;
    box-shadow: inset 0 0 0 2px var(--v2-blue);
}

/* Straddles the card's right border (same border the matching grid column
   below shares) so it lines up with where a user would expect to grab a
   column edge. Handsontable's own manualColumnResize plugin can't offer
   this handle itself -- it only attaches to <th> column headers, and V2
   runs with colHeaders:false (this card band replaces them) -- so the drag
   is driven by hand in home-v2.js, then applied through that same plugin's
   public setManualSize() API (see v2StartColumnResize()). */
.v2-col-resize-handle {
    position: absolute;
    top: 0;
    right: -4px;
    width: 8px;
    height: 100%;
    cursor: col-resize;
    z-index: 2;
    background: transparent;
}

.v2-col-resize-handle:hover,
.v2-col-resize-handle.active {
    background: rgba(37, 99, 235, 0.35);
}

/* While dragging, the pointer routinely ends up outside the 8px handle
   (fast mouse movement) -- pinning the resize cursor to the whole page and
   killing text selection keeps the drag feeling grabbed instead of losing
   it mid-gesture. */
body.v2-col-resizing {
    cursor: col-resize !important;
    user-select: none !important;
}
body.v2-col-resizing * {
    cursor: col-resize !important;
}

.v2-col-name-row {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 4px;
    min-height: 20px;
}

.v2-col-name {
    font-size: 12px;
    font-weight: 700;
    color: var(--v2-heading);
    cursor: pointer;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 100%;
}

.v2-col-rename-btn {
    border: none;
    background: none;
    color: var(--v2-muted);
    cursor: pointer;
    padding: 2px;
    line-height: 1;
    flex: 0 0 auto;
}

.v2-col-rename-btn:hover {
    color: var(--v2-blue);
}

.v2-col-rename-input {
    width: 100%;
    font-size: 12px;
    padding: 2px 4px;
    height: auto;
}

/* TYPE control: a decorative wrap (badge + label + chevron) that owns
   click/keyboard interaction; the real <select> underneath is only a value
   holder + change-event source now (see v2OpenTypeMenu/#v2TypeMenu in
   home-v2.js for the open state) -- its own native popup can't be restyled
   with the badge/spacing/checkmark treatment the open state needs, so the
   wrap handles clicks (pointer-events:none on the <select>) and opens the
   shared, fully-styled #v2TypeMenu instead. */
.v2-col-type-wrap {
    position: relative;
    display: flex;
    align-items: center;
    gap: 6px;
    border: 1px solid var(--v2-border);
    border-radius: 6px;
    background: #ffffff;
    padding: 4px 8px;
    height: auto;
    cursor: pointer;
}

.v2-col-type-wrap:focus-visible {
    outline: 2px solid var(--v2-blue);
    outline-offset: 1px;
}

.v2-col-type-badge {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 1px 5px;
    border-radius: 5px;
    font-size: 10px;
    font-weight: 700;
    line-height: 1.5;
}

.v2-col-type-badge[data-type="STRING"] {
    background: #eef2ff;
    color: #4338ca;
}

.v2-col-type-badge[data-type="NUMBER"] {
    background: #ecfdf5;
    color: #047857;
}

.v2-col-type-badge[data-type="XML"] {
    background: #fff7ed;
    color: #c2410c;
}

.v2-col-type-label {
    flex: 1 1 auto;
    font-size: 11px;
    font-weight: 600;
    color: var(--v2-text);
    text-align: left;
}

.v2-col-type-chevron {
    flex: 0 0 auto;
    font-size: 9px;
    color: var(--v2-muted);
}

.v2-col-type {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    margin: 0;
    padding: 0;
    border: none;
    background: transparent;
    opacity: 0;
    /* The wrap (not this element) owns pointer interaction now -- see the
       comment on .v2-col-type-wrap above. */
    pointer-events: none;
}

/* ---------------- TYPE dropdown (open state): #v2TypeMenu ---------------- */
.v2-col-type-menu {
    position: fixed;
    z-index: 10000;
    background: #ffffff;
    border: 1px solid var(--v2-border);
    border-radius: 8px;
    box-shadow: 0 8px 24px rgba(15, 23, 42, 0.16);
    padding: 4px;
}

.v2-col-type-option {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 8px;
    border-radius: 6px;
    cursor: pointer;
}

.v2-col-type-option:hover {
    background: var(--v2-bg);
}

/* Subtle tint, not a solid color -- keeps the badge's own background/color
   readable instead of being washed out by a strong selected-row fill. */
.v2-col-type-option.selected {
    background: #eef2ff;
}

.v2-col-type-option-label {
    flex: 1 1 auto;
    font-size: 12px;
    font-weight: 600;
    color: var(--v2-text);
    white-space: nowrap;
}

.v2-col-type-check {
    flex: 0 0 auto;
    font-size: 11px;
    color: var(--v2-blue);
    visibility: hidden;
}

.v2-col-type-option.selected .v2-col-type-check {
    visibility: visible;
}

.v2-col-flags {
    display: flex;
    gap: 4px;
}

.v2-flag-btn {
    flex: 1 1 0;
    border: 1px solid var(--v2-border);
    background: #ffffff;
    color: var(--v2-muted);
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.03em;
    padding: 5px 0;
    border-radius: 6px;
    cursor: pointer;
}

.v2-flag-set.active {
    background: var(--v2-green);
    border-color: var(--v2-green);
    color: #ffffff;
}

.v2-flag-where.active {
    background: var(--v2-blue);
    border-color: var(--v2-blue);
    color: #ffffff;
}

.v2-col-original {
    font-size: 10px;
    color: var(--v2-muted);
    text-align: center;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* ---------------- Configure Columns + Grid: one component, no gap ---------------- */
.v2-table-card {
    padding: 12px 0 0;
    position: relative;
    /* Comfortable headroom for .v2-loading-overlay's spinner + text + progress
       bar (now flex-shrink:0, so they no longer compress into that space --
       this just keeps them from being clipped by overflow:hidden below). */
    min-height: 160px;
    overflow: hidden;
}

/* While a new file/table is loading, hide whatever this card was previously
   showing (a prior file's columns and grid) instead of leaving it visible
   behind the progress bar -- see the updateProgress() wrap in home-v2.js. */
.v2-table-card.v2-loading #v2ConfigureSection,
.v2-table-card.v2-loading #table-container,
.v2-table-card.v2-loading #v2EmptyState {
    display: none !important;
}

.v2-loading-overlay {
    display: none;
    position: absolute;
    inset: 0;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 10px;
    padding: 20px;
    background: #ffffff;
}

.v2-table-card.v2-loading .v2-loading-overlay {
    display: flex;
}

.v2-loading-spinner {
    font-size: 22px;
    color: var(--v2-blue);
    flex-shrink: 0;
}

.v2-loading-text {
    font-size: 13px;
    font-weight: 600;
    color: var(--v2-heading);
    flex-shrink: 0;
}

.v2-configure-section {
    padding: 0 16px 9px;
    margin-bottom: 7px;
    border-bottom: 1px solid var(--v2-border);
}

.v2-configure-section .v2-section-title {
    padding: 0 2px;
}

#table-container {
    display: none;
    padding: 0 16px 16px;
}

/* Handsontable's default cell style wraps long content (white-space:pre-wrap)
   instead of truncating it. Columns are capped at ~280px (see
   v2CalcColumnWidth in home-v2.js), so long values must ellipsize on one line
   instead of wrapping/clipping; the full value is still available as a
   native tooltip (set as the cell's title attribute by the grid's renderer). */
#table-container .handsontable td {
    white-space: nowrap;
    text-overflow: ellipsis;
}

.v2-empty-state {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 10px;
    padding: 40px 20px;
    color: var(--v2-muted);
    text-align: center;
}

.v2-empty-state i {
    font-size: 28px;
    color: #c7cbe0;
}

.v2-empty-state p {
    margin: 0;
    font-size: 13px;
    max-width: 320px;
}

/* ---------------- Right column ---------------- */
.v2-label {
    display: block;
    font-size: 12px;
    font-weight: 700;
    color: var(--v2-muted);
    margin-bottom: 6px;
}

.v2-input {
    font-size: 14px;
    width: 100%;
}

.v2-query-settings-title {
    font-size: 13px;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--v2-heading);
    margin: 0 0 12px;
}

/* Table name / Script type side by side (~50/50) on desktop; stacks under
   640px (see below) where a card this narrow can't fit both comfortably. */
.v2-query-settings-row {
    display: flex;
    gap: 12px;
}

.v2-field {
    flex: 1 1 0;
    min-width: 0;
}

.v2-dirty-msg {
    margin-top: 8px;
    font-size: 12px;
    color: #9a3412;
    background: #fff7ed;
    border: 1px solid #fdba74;
    border-radius: 6px;
    padding: 6px 10px;
}

.v2-panel-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    flex-wrap: wrap;
}

.v2-panel-header h3 {
    font-size: 14px;
    font-weight: 700;
    margin: 0;
    display: flex;
    align-items: center;
    gap: 6px;
}

.v2-panel-actions {
    display: flex;
    gap: 10px;
}

.v2-link-btn {
    border: none;
    background: none;
    color: var(--v2-blue);
    font-size: 12px;
    font-weight: 600;
    cursor: pointer;
    padding: 0;
}

.v2-link-btn:hover {
    text-decoration: underline;
}

.v2-set-panel {
    border-color: #bbf7d0;
    background: var(--v2-green-bg);
}

.v2-set-panel h3 {
    color: #14532d;
}

.v2-where-panel {
    border-color: #bfdbfe;
    background: var(--v2-blue-bg);
}

.v2-where-panel h3 {
    color: #1e3a8a;
}

.v2-panel-count {
    font-size: 11px;
    font-weight: 700;
    color: var(--v2-muted);
    margin: 10px 0 8px;
}

.v2-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    min-height: 20px;
}

.v2-chip {
    box-sizing: border-box;
    display: inline-flex;
    align-items: center;
    gap: 2px;
    background: #ffffff;
    border-radius: 999px;
    padding: 0 4px 0 12px;
    height: 28px;
    font-size: 12px;
    font-weight: 600;
    line-height: 1;
}

.v2-chip > span {
    display: inline-flex;
    align-items: center;
    line-height: 1;
}

.v2-chip-set {
    border: 1px solid #86efac;
    color: #14532d;
}

.v2-chip-where {
    border: 1px solid #93c5fd;
    color: #1e3a8a;
}

.v2-chip button {
    box-sizing: border-box;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    border: none;
    background: transparent;
    border-radius: 50%;
    width: 24px;
    height: 24px;
    line-height: 1;
    font-size: 15px;
    cursor: pointer;
    color: inherit;
    padding: 0;
    transition: background 0.15s ease;
}

.v2-chip-set button:hover,
.v2-chip-set button:focus-visible {
    background: rgba(22, 163, 74, 0.16);
}

.v2-chip-where button:hover,
.v2-chip-where button:focus-visible {
    background: rgba(37, 99, 235, 0.16);
}

/* ---------------- Paste Table modal ---------------- */
/* Reuses .custom-modal / .custom-modal-content (site.css) for the overlay
   and dialog chrome, same as #assignFormatDialog/#findReplacePanel; these
   rules only adjust its content layout (wider, left-aligned) and add the
   example table + textarea. */
.v2-paste-modal-content {
    max-width: 480px;
    text-align: left;
}

.v2-paste-modal-content h3 {
    text-align: left;
}

.v2-paste-modal-intro {
    text-align: left;
    font-size: 13px;
    color: var(--v2-muted);
    margin: 0 0 14px;
}

.v2-paste-example {
    background: var(--v2-bg);
    border: 1px solid var(--v2-border);
    border-radius: 8px;
    padding: 10px 12px 8px;
    margin-bottom: 16px;
}

.v2-paste-example-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 12px;
}

.v2-paste-example-table th,
.v2-paste-example-table td {
    padding: 4px 8px;
    text-align: left;
    border-bottom: 1px solid var(--v2-border);
}

.v2-paste-example-table th {
    background: var(--v2-blue-bg);
    color: var(--v2-heading);
    font-weight: 700;
}

.v2-paste-example-table tbody tr:last-child td {
    border-bottom: none;
}

.v2-paste-example-caption {
    margin-top: 6px;
    font-size: 11px;
    font-weight: 600;
    color: var(--v2-blue);
    text-align: center;
}

.v2-paste-label {
    display: block;
    font-size: 13px;
    font-weight: 700;
    color: var(--v2-heading);
    margin-bottom: 6px;
}

.v2-paste-textarea {
    width: 100%;
    min-height: 90px;
    padding: 10px;
    border: 1px solid var(--v2-border);
    border-radius: 8px;
    font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
    font-size: 12px;
    resize: vertical;
    box-sizing: border-box;
}

.v2-paste-modal-actions {
    display: flex;
    justify-content: flex-end;
    margin-top: 14px;
}

/* ---------------- Preview / Generated Script ---------------- */
.v2-preview-subtitle {
    font-size: 11px;
    color: var(--v2-muted);
    font-weight: 600;
}

.v2-preview-box {
    background: #0b1030;
    color: #e5e7f5;
    border-radius: 10px;
    padding: 14px;
    margin: 12px 0 0;
    max-height: 260px;
    overflow: auto;
    font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
    font-size: 12.5px;
    line-height: 1.6;
    white-space: pre-wrap;
    word-break: break-word;
}

.v2-preview-footnote {
    display: flex;
    align-items: flex-start;
    gap: 6px;
    font-size: 11px;
    color: var(--v2-muted);
    margin-top: 8px;
}

.v2-web-limit {
    font-size: 13px;
}

.v2-generate-row {
    display: flex;
    gap: 10px;
}

.v2-generate-row .v2-btn {
    flex: 1 1 0;
    justify-content: center;
}

.v2-generate-footnote {
    font-size: 11px;
    color: var(--v2-muted);
    text-align: center;
    margin-top: -4px;
}

.v2-hidden-textarea,
.v2-hidden-compat {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    opacity: 0;
    pointer-events: none;
}

/* ---------------- Responsive: 1920 / 1366 / tablet ---------------- */
@media (max-width: 1366px) {
    .v2-layout {
        grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr);
    }
}

/* ---------------- Below the generator: SEO content + Desktop Edition ----------------
   Both reuse production content/classes unchanged (.tool-seo-content from
   site.css, .desktop-edition-card and friends from main.css -- both already
   loaded by this page for the reused Find & Replace / Assign Format dialogs
   and the webLimitBox upsell link). Everything here is scoped resets so
   they sit inside/alongside a V2 card instead of visual overrides of those
   shared rules -- site.css and main.css are not touched. This 2-column
   grid is desktop/tablet only; at ≤640px this element is flattened via
   `display: contents` into .v2-main's own single order scheme instead --
   see the "Mobile-only reorder" section further below. */
.v2-below-layout {
    display: grid;
    grid-template-columns: minmax(0, 3fr) minmax(0, 2fr);
    gap: 20px;
    align-items: start;
    margin-top: 20px;
}

.v2-seo-card {
    padding: 0;
    overflow: hidden;
}

/* .tool-seo-content is normally a full-bleed page section: its own
   background/vertical padding, and a Bootstrap .container with its own
   max-width/gutters. Embedded in a .v2-card here instead, so that chrome
   is neutralized and the surrounding .v2-card supplies the background/
   border/radius/padding uniformly with every other V2 card -- the
   heading color and body font underneath are already the same as V2's own
   (--heading-color/--default-font in main.css match --v2-heading and the
   Roboto stack V2 already uses), so no color/font overrides are needed. */
.v2-seo-card .tool-seo-content {
    display: block;
    background: transparent;
    padding: 18px;
}

.v2-seo-card .tool-seo-content .container {
    max-width: none;
    padding: 0;
    margin: 0;
}

.v2-seo-card .tool-seo-content h2 {
    font-size: 20px;
    margin: 0 0 14px;
}

.v2-seo-card .tool-seo-content h3 {
    font-size: 16px;
    margin: 22px 0 10px;
}

.v2-seo-card .tool-seo-content p {
    font-size: 14px;
}

/* .desktop-edition-card already has its own 12px radius and an
   intentionally distinct green-gradient background/border -- that's the
   point of a sales CTA standing out from plain content cards, so unlike
   the SEO content it's placed as-is (not nested inside a second .v2-card),
   just spaced consistently with the rest of this row's right column. */
.v2-desktop-column .desktop-upsell-message {
    margin-top: 0;
}

.v2-desktop-column .desktop-edition-card {
    margin-top: 10px;
}

@media (max-width: 1024px) {
    .v2-layout {
        grid-template-columns: minmax(0, 1fr);
        gap: 12px;
    }

    /* .v2-left/.v2-right are just grouping wrappers (no visual chrome of
       their own) -- collapsing them out of the box tree makes their cards
       direct grid items of .v2-layout instead, so each card can get its
       own `order` below. Without this, the two columns could only be
       reordered as whole blocks, which can't put SQL PREVIEW (inside
       .v2-left) after the Generate/Copy Script buttons (inside .v2-right). */
    .v2-left, .v2-right {
        display: contents;
    }

    .v2-actions-card { order: 1; }
    .v2-source-nav { order: 2; }
    .v2-table-card { order: 3; }
    .v2-query-settings { order: 4; }
    .v2-set-panel { order: 5; }
    .v2-where-panel { order: 6; }
    .v2-web-limit { order: 7; }
    .v2-generate-row { order: 8; }
    #v2GenerateFootnote { order: 9; }
    .v2-preview-card { order: 10; }

    /* Same collapse-to-single-column + reorder technique as .v2-layout
       above: the Desktop Edition upsell (with its "Need unlimited rows..."
       lead-in) comes right after the generated script, ahead of the
       UPDATE-focused SEO content below it. */
    .v2-below-layout {
        grid-template-columns: minmax(0, 1fr);
        gap: 12px;
        margin-top: 12px;
    }

    .v2-seo-column, .v2-desktop-column {
        display: contents;
    }

    .desktop-upsell-message { order: 1; }
    .desktop-edition-card { order: 2; }
    .v2-seo-card { order: 3; }
}

/* ---------------- Phone-only acquisition blocks ----------------
   Hidden here (desktop AND the 641-1024px tablet/responsive-tool range);
   revealed only inside the <=640px query below, per the approved plan:
   tablets keep the existing single-column tool layout without the
   intro/CTA/testimonial/value-section marketing layer. */
.v2-mobile-intro,
.v2-continue-card,
.v2-testimonial-card,
.v2-value-section,
.v2-mobile-generator-intro {
    display: none;
}

/* Tablet (641-1024px, keeps the existing responsive tool layout, no
   acquisition layer) and desktop both need the SAME single visible H1 the
   page was missing entirely -- reusing .v2-mobile-intro's own content
   rather than adding a second section. Deliberately minimal: a compact
   one-line title + subtitle, not a hero -- overrides only display/sizing/
   spacing, the phone-only ≤640px block below is untouched. */
@media (min-width: 641px) {
    .v2-mobile-intro {
        display: block;
        grid-column: 1 / -1;
        padding: 0 0 14px;
        margin-bottom: 6px;
        border-bottom: 1px solid var(--v2-border);
    }

    .v2-mobile-intro h1 {
        margin: 0 0 4px;
        font-size: 19px;
        font-weight: 800;
        color: var(--v2-heading);
        line-height: 1.3;
    }

    .v2-mobile-intro p {
        margin: 0;
        font-size: 13px;
        line-height: 1.4;
        color: var(--v2-muted);
    }
}

@media (max-width: 640px) {
    /* Keeps the topbar from wrapping to a second (taller) line on narrow
       screens now that it also carries the page title. */
    .v2-topbar-title {
        display: none;
    }

    .v2-query-settings-row {
        flex-direction: column;
        gap: 14px;
    }

    .v2-main {
        padding: 20px 14px 40px;
    }

    .v2-generate-row {
        flex-direction: column;
    }

    /* -------- Import actions: 2-column grid instead of wrapping flex -------- */
    .v2-action-buttons {
        display: grid;
        grid-template-columns: 1fr 1fr;
        gap: 8px;
    }

    .v2-action-buttons .v2-btn {
        justify-content: center;
    }

    /* main.css (shared production stylesheet, not touched here) has its own
       #btnLoadExcel/#btnClean/#btnPaste/#btnPasteExample rules for
       production's own (asymmetric) mobile button layout, active <=768px.
       V2 reuses those exact element ids for its own buttons, so those
       declarations (grid-column, width, padding, font-weight) leak through
       and fight this 2x2 grid -- reset them back to .v2-btn's own values
       instead of editing main.css. */
    #btnLoadExcel,
    #btnPaste,
    #btnPasteExample,
    #btnClean {
        grid-column: auto;
        width: auto;
        padding: 10px 16px;
        font-weight: 600;
        font-size: 14px;
    }

    /* Total Records: sits on its own row below the 2x2 grid, kept visually
       secondary (already smaller/muted -- see .v2-total-records) rather
       than fighting the buttons for a column. */
    .v2-total-records {
        grid-column: 1 / -1;
        margin-left: 0;
        text-align: right;
    }

    /* -------- SET/WHERE/INCLUDE panel header: actions on their own row -------- */
    .v2-panel-header {
        flex-direction: column;
        align-items: flex-start;
        gap: 6px;
    }

    .v2-panel-actions {
        align-self: flex-end;
    }

    /* -------- Phone-only acquisition blocks: reveal --------
       .v2-mobile-intro is legacy/vestigial (no matching element on the five
       production pages any more -- see generate-update-sql-v2.html, the
       untouched reference prototype, which still uses it); its order is
       left as-is and has no visible effect here. The mobile `order` for
       .v2-continue-card/.v2-testimonial-card/.v2-value-section (and
       Desktop Edition/the generator/SEO content) is set together, in one
       place, further below -- see that section's comment for why. */
    .v2-mobile-intro {
        display: block;
        order: -2;
    }

    .v2-continue-card {
        display: flex;
    }

    .v2-testimonial-card {
        display: block;
    }

    .v2-value-section {
        display: block;
    }

    .v2-mobile-intro {
        padding: 4px 2px 2px;
    }

    .v2-mobile-intro h1 {
        margin: 0 0 6px;
        font-size: 22px;
        font-weight: 800;
        color: var(--v2-heading);
        line-height: 1.25;
    }

    .v2-mobile-intro p {
        margin: 0;
        font-size: 14px;
        line-height: 1.5;
        color: var(--v2-muted);
    }

    .v2-continue-card {
        flex-direction: column;
        gap: 10px;
        padding: 14px;
        border: 1px solid #bfdbfe;
        background: var(--v2-blue-bg);
        border-radius: 12px;
    }

    .v2-continue-text {
        display: flex;
        flex-direction: column;
        gap: 3px;
    }

    .v2-continue-text strong {
        font-size: 14px;
        color: var(--v2-heading);
    }

    .v2-continue-text span {
        font-size: 13px;
        line-height: 1.45;
        color: var(--v2-text);
    }

    .v2-continue-btn {
        display: flex;
        align-items: center;
        justify-content: center;
        gap: 8px;
        border: none;
        border-radius: 10px;
        padding: 12px 14px;
        background: var(--v2-blue);
        color: #ffffff;
        font-weight: 700;
        font-size: 14px;
        cursor: pointer;
    }

    .v2-continue-btn:hover {
        background: #1d4ed8;
    }

    .v2-testimonial-card {
        padding: 16px;
    }

    .v2-testimonial-card > i {
        font-size: 16px;
        color: var(--v2-blue);
        opacity: 0.55;
    }

    .v2-testimonial-card p {
        margin: 8px 0 10px;
        font-size: 14px;
        line-height: 1.5;
        color: var(--v2-text);
    }

    .v2-testimonial-card p strong {
        color: var(--v2-heading);
    }

    .v2-testimonial-attribution {
        display: flex;
        flex-direction: column;
        gap: 1px;
    }

    .v2-testimonial-name {
        font-size: 13px;
        font-weight: 700;
        color: var(--v2-heading);
    }

    .v2-testimonial-role {
        font-size: 12px;
        color: var(--v2-muted);
    }

    .v2-value-section h2 {
        font-size: 16px;
        font-weight: 800;
        color: var(--v2-heading);
        margin: 0 0 10px;
    }

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

    .v2-value-card {
        border: 1px solid var(--v2-border);
        border-radius: 12px;
        background: #ffffff;
        padding: 12px 14px;
    }

    .v2-value-card i {
        font-size: 15px;
        color: var(--v2-blue);
    }

    .v2-value-card h4 {
        margin: 6px 0 3px;
        font-size: 13.5px;
        font-weight: 700;
        color: var(--v2-heading);
    }

    .v2-value-card p {
        margin: 0;
        font-size: 12.5px;
        line-height: 1.45;
        color: var(--v2-muted);
    }

    /* -------- Shared simplified-mobile-demo rule: all 6 pages --------
       Upload Excel/Paste Table/Example Data/Clear Data (.v2-actions-card)
       and the SET/WHERE summary cards (which just repeat what's already
       configurable per-column in Configure Columns) are hidden at this
       breakpoint everywhere the shared generator is used -- Home and the
       five generate-*.html pages alike now want the exact same "simplified
       interactive demo" mobile experience. Previously two near-identical
       rules (one Home-scoped via :has(), one implicit for generate-*);
       unified into one, since no page wants these visible here anymore.
       All three are grid items of #script-container (directly, or via
       .v2-left/.v2-right's existing display:contents at ≤1024px above)
       with order:1/5/6; display:none removes each from the grid entirely
       (no empty gap left behind), so the remaining cards (table-card:3,
       query-settings:4, generate-row:8, preview-card:10) naturally
       collapse into: Configure Columns -> Query Settings -> Generate/Copy
       -> SQL Preview, with no new `order` value needed for any of them. */
    .v2-actions-card,
    .v2-set-panel,
    .v2-where-panel {
        display: none;
    }

    /* -------- generate-*.html only: Desktop Edition + SEO content reorder --------
       Desktop Edition (.desktop-upsell-message/.desktop-edition-card, inside
       .v2-below-layout > .v2-desktop-column) and the SEO content
       (.v2-seo-card, inside .v2-below-layout > .v2-seo-column) live in a
       SEPARATE CSS grid from .v2-layout/#script-container -- both are
       siblings under .v2-main, not nested. `order` only reorders items
       within the SAME flex/grid formatting context, so it cannot by itself
       interleave them with .v2-continue-card/.v2-testimonial-card/
       .v2-value-section (children of #script-container) or with the
       generator. Fix: at this breakpoint only, flatten both grids into
       .v2-main itself via `display: contents` (the same technique already
       used for .v2-left/.v2-right above, and for .v2-seo-column/
       .v2-desktop-column at ≤1024px), so every card becomes a direct flex
       item of .v2-main and can share one `order` scheme. No HTML moves or
       duplicates any element -- this only changes which box each existing
       element renders inside.
       Scoped to `.v2-main:has(> .v2-page-h1)` so this can never affect
       index.html's own .v2-main, which reuses the same class but has a
       different set of children (#homeTestimonial, #about, #demo-video...)
       and no .v2-page-h1/.v2-below-layout of its own -- index.html's
       .v2-main keeps its default (non-flex) display at every width, and
       reaches the same visual result (generator, then .v2-continue-card,
       see its own `order:11` below) through its own plain DOM order
       instead, since it never had these blocks inside #script-container's
       grid to begin with.
       Desktop/tablet (>640px) are untouched: this whole rule lives inside
       this ≤640px query, so .v2-layout/.v2-below-layout keep their normal
       display:grid there. */
    .v2-main:has(> .v2-page-h1) {
        display: flex;
        flex-direction: column;
        gap: 12px;
    }

    .v2-main:has(> .v2-page-h1) > .v2-layout,
    .v2-main:has(> .v2-page-h1) > .v2-below-layout {
        display: contents;
    }

    /* Single order scheme for everything .v2-main (generate-*.html pages)
       now directly contains at this breakpoint. Generator cards keep their
       existing order: 1-10 (set in the ≤1024px query above) unchanged.
       .v2-continue-card's order:11 below is shared with Home (see its own
       comment there) -- both pages want it right after the generator/SQL
       Preview now, so one declaration covers both instead of two near-
       identical page-scoped ones. Testimonial/value-section/Desktop
       Edition keep their previous relative order among each other, just
       shifted from "before the generator" to "after .v2-continue-card". */
    .v2-page-h1 { order: -20; }
    .v2-testimonial-card { order: 12; }
    .v2-value-section { order: 13; }
    .desktop-upsell-message { order: 14; }
    .desktop-edition-card { order: 15; }
    .v2-seo-card { order: 20; }

    /* "Or use the web generator" (.v2-mobile-generator-intro) no longer has
       a role now that the generator comes right after the H1 instead of
       after this marketing content -- by the time a visitor would reach
       this text, they've already used the generator above. Left hidden via
       its existing default (unscoped, all viewports) `display:none` rule
       further up this file -- not repositioned, reworded or replaced, and
       the element itself stays in the DOM/HTML unchanged. */

    /* .v2-continue-card: shared by Home and the five generate-*.html pages
       (see the "Shared simplified-mobile-demo rule" above for the same
       reasoning applied to actions-card/set-panel/where-panel) -- both now
       want it right after the generator/SQL Preview (order 10), so one
       unscoped rule replaces what used to be two page-scoped ones. */
    .v2-continue-card { order: 11; }
}

/*--------------------------------------------------------------
# index.html-only sections: standalone testimonial + benefits grid.
#
# The five generate-*.html pages reuse .v2-testimonial-card/.v2-value-section
# as PHONE-ONLY marketing blocks living inside .v2-layout (display:none
# above 640px, "order" positioned among the generator's own cards -- see
# the "Phone-only acquisition blocks" section above). index.html needs the
# same visual language, but as always-visible standalone sections placed
# AFTER the generator -- a different enough layout role that reusing the
# bare classes unscoped would either be hidden by that phone-only default
# or need !important fighting it at every width. Every rule below is
# scoped under #homeTestimonial / #about, which only exist in index.html's
# DOM, so this cannot affect the five generate-*.html pages and their
# ≤640px rules above cannot affect index.html.
--------------------------------------------------------------*/

#homeTestimonial {
    margin-top: 24px;
}

#homeTestimonial .v2-testimonial-card {
    display: block;
    max-width: 640px;
    margin: 0 auto;
    padding: 22px 26px;
    text-align: center;
}

#homeTestimonial .v2-testimonial-card > i {
    font-size: 20px;
    color: var(--v2-blue);
    opacity: 0.5;
}

#homeTestimonial .v2-testimonial-card p {
    margin: 10px 0 14px;
    font-size: 16px;
    line-height: 1.55;
    color: var(--v2-text);
}

#homeTestimonial .v2-testimonial-card p strong {
    color: var(--v2-heading);
}

#homeTestimonial .v2-testimonial-attribution {
    display: flex;
    flex-direction: column;
    gap: 1px;
}

#homeTestimonial .v2-testimonial-name {
    font-size: 14px;
    font-weight: 700;
    color: var(--v2-heading);
}

#homeTestimonial .v2-testimonial-role {
    font-size: 13px;
    color: var(--v2-muted);
}

/* #about doubles as the "What can TableToSQL save you from?" benefits
   grid AND the required #about anchor (shared header + footer both link
   to it) -- .home-benefits scopes this new styling without touching
   .v2-value-section's own phone-only rules above. */
#about.home-benefits {
    margin-top: 28px;
}

#about.home-benefits h2 {
    font-size: 22px;
    font-weight: 800;
    color: var(--v2-heading);
    text-align: center;
    margin: 0 0 18px;
}

#about.home-benefits .v2-value-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 14px;
}

#about.home-benefits .v2-value-card {
    display: block;
    border: 1px solid var(--v2-border);
    border-radius: 12px;
    background: #ffffff;
    padding: 18px 20px;
}

#about.home-benefits .v2-value-card i {
    font-size: 20px;
    color: var(--v2-blue);
}

#about.home-benefits .v2-value-card h4 {
    margin: 10px 0 6px;
    font-size: 15px;
    font-weight: 700;
    color: var(--v2-heading);
}

#about.home-benefits .v2-value-card p {
    margin: 0;
    font-size: 13.5px;
    line-height: 1.5;
    color: var(--v2-muted);
}

@media (max-width: 640px) {
    #about.home-benefits .v2-value-grid {
        grid-template-columns: 1fr;
    }
}

/* index.html's #demo-video/#privacy/#contact now sit inside .v2-main (moved
   from the old full-bleed .main wrapper) -- #demo-video keeps ALL of its own
   styling from site.css's .demo-video.section (background/padding/grid)
   untouched, this only adds the top spacing .v2-main's stacked sections need
   between each other. */
#demo-video.section {
    margin-top: 28px;
}

#privacy .v2-card,
#contact .v2-card {
    margin-top: 20px;
}
