/*
 * Copyright (c) Biovisuals Private Limited. All rights reserved.
 *
 * TABLET-PORTRAIT BOTTOM CREATION BAR (768-899px).
 *
 * Everything here is keyed off `#app-studio[data-bv-mode="portrait"]` or the
 * `html.bv-shell-portrait` mirror — never off a width media query. The responsive
 * shell owns the authoritative mode; this file only dresses it. (`html.bv-shell-portrait`
 * exists because `#openCallPanelBtn` is a SIBLING of `.app`, not a descendant, so a
 * descendant selector cannot reach it.)
 *
 * The bar is `position: fixed` and lives outside the shell grid, so nothing in this file
 * can change `.svg-canvas-container`'s content box or Fabric's dimensions.
 */

/* ── the rail is retired in portrait ──────────────────────────────────────────
   Collapsing the grid track as well as hiding the element is what actually returns the
   60px to the canvas. This is a MODE change, not a panel toggle, so the single Fabric
   sync it causes is the same one every mode change already causes.

   ⚠️ THE SELECTOR LIST BELOW IS LOAD-BEARING. D3.1 CORRECTION.

   `--bv-rail-w: 60px` is declared on `.app` (global.css), and `.app` is also the grid
   container whose `grid-template-columns` consumes it. `#app-studio` is its PARENT
   (index.html: `<div id="app-studio"><div class="app">`). A custom property declared ON an
   element always wins over the value it would inherit from its parent — so scoping the
   override to `#app-studio` alone left `.app`'s own `60px` declaration in force, and the
   first grid track kept reserving 60px in portrait even though the rail element inside it was
   `display: none`. The canvas started 60px in from the shell's left edge.

   The existing portrait test did not catch it because it read the property off `#app-studio`,
   which is precisely where the override WAS applied.

   Both element shapes are therefore listed, exactly as the portrait left-dock suppression in
   `slider-container.css` already does for `--bv-left-dock`. */
#app-studio[data-bv-mode="portrait"],
#app-studio[data-bv-mode="portrait"] .app,
#app-studio[data-bv-mode="portrait"].app {
    --bv-rail-w: 0px;
}

/* `display: none` alone already removes the rail from layout AND from hit-testing. The two
   extra declarations are explicit statements of the D3.1 requirement rather than load-bearing
   rules: the rail must occupy zero width and must never intercept a pointer, touch, wheel or
   contextmenu event — in particular it must not sit above the canvas and swallow the
   right-click that the Studio's own canvas menu needs. Stating them means a future change that
   makes the rail visible-but-empty (or animates it) cannot silently reintroduce either
   problem. */
#app-studio[data-bv-mode="portrait"] .image-library {
    display: none;
    width: 0;
    min-width: 0;
    pointer-events: none;
}

/* ── the bar ──────────────────────────────────────────────────────────────── */
.bv-createbar {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 1003;      /* above the sheet (1001) and the top toolbar's 1002 stacking */
    display: flex;
    align-items: stretch;
    gap: 6px;
    box-sizing: border-box;
    /* 60px of controls + the device's own bottom inset. Lands inside the 56-64px
       target on every tablet, and never under a home indicator. */
    min-height: 60px;
    padding: 4px 8px calc(4px + env(safe-area-inset-bottom, 0px));
    background: #ffffff;
    border-top: 1px solid #d9dde3;
    box-shadow: 0 -6px 18px rgba(16, 24, 40, 0.12);
}
.bv-createbar[hidden] { display: none; }

/* Scrolls ONLY if the primary row genuinely overflows. D3.1's seven primary slots still
   fit 768px with room to spare (arithmetic on `.bv-createbar__slot` below), so this stays
   a safety valve rather than the normal state — but it is the DELIBERATE overflow
   behaviour: the row scrolls horizontally, it never wraps to a second line and never
   shrinks a target below 44px. */
.bv-createbar__scroll {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    align-items: stretch;
    gap: 4px;
    overflow-x: auto;
    overflow-y: hidden;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior-x: contain;
}
.bv-createbar__scroll::-webkit-scrollbar { display: none; }

/* SEVEN primary slots plus More = eight targets (D3.1). `min-width` is a FLOOR, not a
   target: with `flex: 1 1 auto` the slots share the width they have, and because they can
   never shrink past 56px the scroller above takes over instead of squeezing a target below
   the touch minimum or wrapping the bar onto a second row.

   The narrowest supported portrait width is 768px. Budget there:
     752px  content box            (768 - 2x8px bar padding)
     -56px  More button floor
      -6px  bar gap before More
     ─────
     690px  available to the scroller
     -24px  six 4px inter-slot gaps
     ─────
     666px  shared by 7 slots  ->  ~95px each, well clear of both the 56px slot floor
            and the 44px button minimum, so the scroller stays idle at every supported
            portrait width and engages only if a future build adds a ninth target. */
.bv-createbar__slot {
    flex: 1 1 auto;
    min-width: 56px;
    display: flex;
    align-items: stretch;
    justify-content: center;
}

/* ── hosted controls ──────────────────────────────────────────────────────────
   These are the REAL rail/toolbar controls, moved here by portraitCreationBar.js. Only
   presentation is restated; no control is re-created, so every handler, every plan gate
   and every anchored popup travels with it. */
.bv-createbar .bv-createbar__hosted,
.bv-createbar__slot > .bv-createbar__hosted {
    flex: 1 1 auto;
    display: flex;
    position: relative;
}

.bv-createbar__slot button,
.bv-createbar__btn {
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 2px;
    /* >=44px in both directions. */
    min-width: 44px;
    min-height: 44px;
    padding: 4px 6px;
    box-sizing: border-box;
    background: transparent;
    border: 0;
    border-radius: 10px;
    color: #1b263b;
    font-family: 'Arial', 'Helvetica', sans-serif;
    font-size: 10px;
    line-height: 1.15;
    font-weight: 600;
    text-align: center;
    white-space: nowrap;
    cursor: pointer;
}
.bv-createbar__slot button > i,
.bv-createbar__btn > i,
.bv-createbar__slot button > svg {
    font-size: 17px;
    line-height: 1;
}
/* Rail buttons carry an <img> glyph rather than an icon font. */
.bv-createbar__slot button > img {
    width: 20px;
    height: 20px;
    object-fit: contain;
}
.bv-createbar__slot button > span,
.bv-createbar__btn > .bv-createbar__label {
    display: block;
    max-width: 68px;
    overflow: hidden;
    text-overflow: ellipsis;
    font-size: 10px;
    font-weight: 600;
}
/* `<br>` inside a rail label ("AI <br> Layout") would double the bar's height. */
.bv-createbar__slot button br,
.bv-createbar-panel__row button br { display: none; }

.bv-createbar__slot button:hover,
.bv-createbar__btn:hover { background: #eef1f5; }
.bv-createbar__slot button.active,
.bv-createbar__slot button[aria-pressed="true"] { background: #fff1e2; color: #b34b00; }
.bv-createbar__slot button:focus-visible,
.bv-createbar__btn:focus-visible { outline: 2px solid #ff6f00; outline-offset: 2px; }

.bv-createbar__more { flex: 0 0 auto; min-width: 56px; }

/* ── relocated desktop popups ─────────────────────────────────────────────────
   A popup authored for a TOP toolbar opens downward (`position: absolute; top: 100%`).
   Relocated to the bottom bar that puts it off the bottom of the screen and behind the
   bar. Two mechanisms cover this:

   1. Popups still inside the bar get a fixed, bar-relative box here.
   2. Popups launched from the More disclosure are PORTALLED to `document.body` by
      portraitPopupPlacement.js and carry `[data-bv-portrait-popup]`; that module writes
      `left`/`top`/`max-height` from the live visual viewport, so this rule only has to
      neutralise the authored `absolute`/`top: 100%`/fixed-width assumptions and put the
      surface above the bar in the stacking order. */
.bv-createbar .shapes-container,
.bv-createbar #shapesContainer,
.bv-createbar #resizeCanvasOptions,
.bv-createbar .line-type-dropdown,
.bv-createbar #lineToolsDropdown,
.bv-createbar .text-type-dropdown,
.bv-createbar .dropdown-content,
.bv-createbar .text-type-dropdown.show {
    position: fixed;
    bottom: calc(64px + env(safe-area-inset-bottom, 0px));
    top: auto;
    left: 8px;
    right: 8px;
    max-height: 46dvh;
    overflow-y: auto;
    z-index: 1004;
}

/* A portalled popup. `top`/`left`/`max-height`/`width` are written by JS from the visual
   viewport; `bottom`/`right: auto` is what stops the authored offsets from fighting them. */
[data-bv-portrait-popup] {
    position: fixed !important;
    bottom: auto !important;
    right: auto !important;
    margin: 0 !important;
    /* So the width JS writes IS the rendered width. Several of these popups are authored
       content-box with padding, and positioning from a written width that the browser then
       grows by the padding is what put a surface 8px off centre from its trigger. The placer
       re-measures as well, so this is belt and braces rather than the only guard. */
    box-sizing: border-box !important;
    overflow-y: auto;
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
    z-index: 1005;   /* above the bar (1003) and its More panel (1004) */
}

/* ── hover must not reopen a portrait surface ──────────────────────────────────
   `.shape-type-dropdown` and `.line-type-dropdown` are revealed on DESKTOP by a `:hover` rule
   on their wrapper. In portrait that rule is actively harmful: once a close path hands the
   node back to its wrapper inside the bar, a pointer still resting on the trigger — a stylus,
   a trackpad, or the emulated hover a tap leaves behind — re-satisfies `:hover` and the
   surface reappears the instant it was dismissed. Escape, an outside tap, a command switch and
   rotation all looked like they had no effect.

   Portrait is touch-first, so the explicit `.show` state is the only opener there. `:not(.show)`
   is what keeps that authoritative rather than fighting it.

   Keyed on `html.bv-shell-portrait` rather than `#app-studio[data-bv-mode]` because in portrait
   these controls have been MOVED into `#bvCreationBar`, which is appended to `document.body` and
   is therefore not a descendant of the shell. */
html.bv-shell-portrait .shape-toggle-container:hover .shape-type-dropdown:not(.show),
html.bv-shell-portrait .dropdown:hover .line-type-dropdown:not(.show),
html.bv-shell-portrait .dropdown:hover .text-type-dropdown:not(.show) {
    display: none;
}

/* `env()` cannot be read from JS, so the safe-area insets are mirrored into custom
   properties for portraitPopupPlacement.js and portraitStyleInspector.js to read back when
   they clamp.

   D3.1 mirrors ALL FOUR edges, not just the bottom. A tablet with a rounded display or a
   notch reports a top inset in portrait, and left/right insets appear as soon as the device
   is held with the home indicator on a side. Clamping a popover to the raw viewport put it
   underneath those. */
:root {
    --bv-safe-top: env(safe-area-inset-top, 0px);
    --bv-safe-right: env(safe-area-inset-right, 0px);
    --bv-safe-bottom: env(safe-area-inset-bottom, 0px);
    --bv-safe-left: env(safe-area-inset-left, 0px);
}

/* ── the More panel ─────────────────────────────────────────────────────────── */
.bv-createbar-panel {
    position: fixed;
    z-index: 1004;
    display: grid;
    grid-template-columns: repeat(2, minmax(120px, 1fr));
    gap: 4px;
    min-width: 260px;
    max-width: min(360px, calc(100vw - 16px));
    max-height: 52dvh;
    overflow-y: auto;
    padding: 8px;
    background: #ffffff;
    border: 1px solid #d9dde3;
    border-radius: 12px;
    box-shadow: 0 12px 32px rgba(16, 24, 40, 0.2);
}
.bv-createbar-panel[hidden] { display: none; }

.bv-createbar-panel__row { display: flex; position: relative; }

.bv-createbar-panel__row button,
.bv-createbar-panel__row .dropbtn,
.bv-createbar-panel__row .top-btn {
    flex: 1 1 auto;
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: flex-start;
    gap: 10px;
    min-height: 44px;
    padding: 8px 10px;
    box-sizing: border-box;
    background: transparent;
    border: 0;
    border-radius: 8px;
    color: #1b263b;
    font-family: 'Arial', 'Helvetica', sans-serif;
    font-size: 12px;
    font-weight: 600;
    text-align: left;
    white-space: nowrap;
    cursor: pointer;
}
.bv-createbar-panel__row button > i { font-size: 15px; width: 18px; text-align: center; }
.bv-createbar-panel__row button > img { width: 18px; height: 18px; object-fit: contain; }
.bv-createbar-panel__row button:hover { background: #eef1f5; }
.bv-createbar-panel__row button:focus-visible { outline: 2px solid #ff6f00; outline-offset: 2px; }

/* ── bottom canvas controls lift above the bar / sheet ────────────────────────
   `--bv-bottom-obstruction` is published by bottomSheet.js on the document element and
   is the single number every bottom-anchored surface reads. `--bv-panbar-bottom-offset`
   already derives from `--bv-canvas-bottom-inset` (global.css), so redefining that one
   variable moves the zoom toolbar and the pan bar together instead of drifting apart.

   ⚠️ `.app` IS IN THIS SELECTOR LIST ON PURPOSE — D3.2 §8.
   `--bv-canvas-bottom-inset` is DECLARED on `.app` in `global.css`. In production
   `#app-studio` is the PARENT of `.app` (`index.html`: `<div id="app-studio"><div
   id="Biovisuals Studio" class="app">`), so an override written only on `#app-studio` is
   INHERITED by `.app` — and then immediately shadowed by `.app`'s own declaration. The zoom
   toolbar and the pan bar therefore never lifted in production.
   It passed every existing spec because the test harness collapses the two into one element
   (`<div id="app-studio" class="app">`), where the override and the declaration land on the
   same node and the more specific selector wins. Naming both means the override applies whether
   they are one node or two. Same class of bug as the D3.1 `--bv-rail-w` correction. */
#app-studio[data-bv-mode="portrait"],
#app-studio[data-bv-mode="portrait"] .app,
html.bv-shell-portrait .app {
    --bv-canvas-bottom-inset: calc(8px + var(--bv-bottom-obstruction, 0px));
}

html.bv-shell-portrait #openCallPanelBtn {
    bottom: calc(20px + var(--bv-bottom-obstruction, 0px));
    /* Comfortably clear of the pan bar's right margin at portrait widths. */
    width: 48px;
    height: 48px;
    font-size: 20px;
}

/* ── the Draw controls ────────────────────────────────────────────────────────
   D3.2 §8. `.draw-control-panel` is `position: fixed; bottom: 20px; left: 20px; z-index: 1000`
   in `additional-styles.css`, which in portrait put it squarely underneath the creation bar:
   measured at 820x1180 the visible panel occupies y 1102-1160 while the bar occupies
   y 1120-1180, so 40 of its 58px sat inside the bar's band — and the bar wins at z-index 1003.
   `additional-styles.css` also has an `@media (max-width: 768px) { bottom: 10px }` rule that
   makes it WORSE at exactly the narrowest supported portrait width.

   Routed through the SAME `--bv-bottom-obstruction` number as the zoom toolbar, the pan bar and
   the support button rather than given a bespoke offset, so it tracks the bar AND the sheet at
   every state instead of being pinned to one screenshot's measurement. `draw.js` needs no
   change: it only toggles `.hidden`, and this is pure positioning. */
html.bv-shell-portrait .draw-control-panel {
    /* `bottom` is restated with the same 20px base the desktop rule uses, so the only thing
       this changes is the added clearance. The `@media (max-width: 768px)` 10px variant is
       overridden here because at portrait widths it is the case that needs MORE room, not less. */
    bottom: calc(20px + var(--bv-bottom-obstruction, 0px));
    /* Above the creation bar (1003) and the sheet (1001): when the panel is lifted clear it must
       be the thing the user can see and reach, not something painted behind the bar it was just
       moved above. Still below the floating object toolbar (99999) and the inspector (100002),
       which are contextual to a selection and outrank an ambient tool panel. */
    z-index: 1004;
    /* At 768px the panel's natural width plus a 20px left offset can exceed the viewport. */
    max-width: calc(100vw - 40px);
    /* The controls row is allowed to wrap rather than overflow horizontally. */
    flex-wrap: wrap;
}

/* At EXPANDED the sheet covers the whole canvas cell, so there is nowhere left to lift the
   bottom controls into — an offset that large would push them off screen instead. They are
   hidden while the canvas they act on is not visible, and return the moment the sheet drops
   back to half or peek. Nothing is disabled or unmounted; this is visibility only.

   D3.2 §8 adds `.draw-control-panel` to the set: it was the one bottom-anchored surface the
   rule did not cover, so at expanded it was the only thing left floating over a sheet that had
   taken the entire canvas. */
html.bv-sheet-open.bv-sheet-expanded .floating-zoom,
html.bv-sheet-open.bv-sheet-expanded .bv-panbar,
html.bv-sheet-open.bv-sheet-expanded .draw-control-panel,
html.bv-sheet-open.bv-sheet-expanded #openCallPanelBtn {
    display: none;
}

/* ── presentation ─────────────────────────────────────────────────────────────
   Presentation builds its own fullscreen container, so a fixed sibling outside it is not
   painted anyway. These rules make that explicit rather than relying on it, and cover any
   path that presents without fullscreen.

   `bv-presenting`, NOT `presenting`: `additional-styles.css` carries dormant `body.presenting`
   rules that nothing currently sets, and adopting that class name would silently activate a
   block of never-reviewed CSS during presentation. Presentation behaviour must be unchanged
   by this slice. */
body.bv-presenting #bvCreationBar,
body.bv-presenting #bvCreationMorePanel,
body.bv-presenting .bv-sheet-grip {
    display: none !important;
}

/* ── the rotate hint ──────────────────────────────────────────────────────────
   Advisory only: it never blocks presenting, never covers the slide, and is dismissible.
   Shown only while presenting at a portrait aspect. */
#bvRotateHint {
    position: fixed;
    left: 50%;
    transform: translateX(-50%);
    bottom: calc(18px + env(safe-area-inset-bottom, 0px));
    z-index: 100001;
    display: none;
    align-items: center;
    gap: 10px;
    max-width: min(420px, calc(100vw - 32px));
    padding: 9px 10px 9px 14px;
    background: rgba(24, 28, 34, 0.9);
    color: #fff;
    border-radius: 999px;
    font-family: 'Arial', 'Helvetica', sans-serif;
    font-size: 12.5px;
    line-height: 1.25;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.3);
}
body.bv-presenting.bv-portrait-presenting #bvRotateHint:not([data-bv-dismissed="true"]) {
    display: flex;
}
#bvRotateHint button {
    flex: 0 0 auto;
    min-width: 32px;
    min-height: 32px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: rgba(255, 255, 255, 0.16);
    border: 0;
    border-radius: 50%;
    color: #fff;
    font-size: 14px;
    cursor: pointer;
}
#bvRotateHint button:hover { background: rgba(255, 255, 255, 0.28); }
#bvRotateHint button:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }

@media (prefers-reduced-motion: reduce) {
    .bv-createbar,
    .bv-createbar-panel,
    #bvRotateHint { transition: none !important; }
}
