/* CSS Shape Generator - the studio chrome comes from .gn-studio-* in
   css/common.css; this file is only what is specific to shapes. */

/* Inline mode (the per-shape landing pages) is a framed panel in the page
   column rather than a fullscreen workspace */
.csg-inline {
    height: 520px;
    border: 1px solid var(--gn-card-border);
    border-radius: 0.75rem;
    overflow: hidden;
}

/* A fixed width, not just a fixed basis. A flex item's automatic minimum
   size is its content's, so the code block's longest line was widening the
   panel - which made it a different width on every shape. */
.csg .gn-studio-panel {
    flex: 0 0 330px;
    min-width: 0;
}

.csg .app-side-body,
.csg .app-side-footer {
    min-width: 0;
}

/* The studio frame is a plain box that a canvas is dropped into. Nothing
   here is a picture with edges to align to, so the shape belongs in the
   middle of the stage rather than in its top-left corner. */
.csg .gn-studio-frame {
    display: flex;
    align-items: center;
    justify-content: center;
}

/* The sized box the shape is drawn in. It is kept at the shape's own
   aspect ratio so nothing is silently squashed, and the handle overlay
   sits exactly on top of it. */
.csg-canvas {
    position: relative;
}

/* Points on screen: the canvas is the point editor, not the rotation
   knob, so it must not advertise itself with the stage's grab cursor.
   The handles set their own. */
.csg-canvas.csg-editing {
    cursor: default;
}

/* This element carries the generated declarations verbatim - the preview
   and the copied code can never disagree. position: relative because the
   border's second layer is an absolutely positioned ::after, exactly as
   the generated rule has it. */
.csg-shape {
    position: relative;
    width: 100%;
    height: 100%;
    box-sizing: border-box;
}

.csg-handles {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    overflow: visible;
    touch-action: none;
}

.csg-handle {
    fill: #fff;
    stroke: var(--gn-accent);
    stroke-width: 0.6;
    vector-effect: non-scaling-stroke;
    cursor: grab;
}

.csg-handle:hover {
    fill: var(--gn-accent);
}

.csg-handles:active .csg-handle {
    cursor: grabbing;
}

/* Prev / next / browse share the select's border */
.csg-nav {
    border: 1px solid var(--bs-border-color);
    color: var(--gn-muted);
    background: none;
}

.csg-nav:hover {
    border-color: var(--bs-border-color);
    background-color: var(--gn-sidebar-hover-bg);
    color: var(--gn-accent);
}

.csg-colors {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 0.25rem 0;
}

.csg-check {
    padding-top: 0.35rem;
}

.csg-hint {
    font-size: 0.78rem;
    color: var(--gn-muted);
    margin: 0.25rem 0 0;
}

/* Label, help mark and live value on one row. The shared .gn-studio-label
   is a block carrying its own top margin; in a row that margin belongs to
   the row, and the value swaps its float for an auto margin. */
.csg-labelrow {
    display: flex;
    align-items: center;
    gap: 0.35rem;
    margin-top: 0.5rem;
}

.csg-labelrow .gn-studio-label {
    margin-top: 0;
    margin-bottom: 0;
}

.csg-labelrow .gn-studio-val {
    float: none;
    margin-left: auto;
}

/* A question mark beside the heading instead of a paragraph below the
   control: quiet until asked, and it costs no vertical space. */
.csg-help {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 15px;
    height: 15px;
    padding: 0;
    border: 1px solid var(--gn-card-border);
    border-radius: 50%;
    background: none;
    color: var(--gn-muted);
    font-size: 0.62rem;
    line-height: 1;
}

.csg-help:hover,
.csg-help[aria-expanded="true"] {
    border-color: var(--gn-accent);
    color: var(--gn-accent);
}

/* The shared popover is sized for grids of swatches; this one holds prose */
.csg-help-text {
    max-height: none;
    padding: 0.5rem 0.6rem;
    font-size: 0.72rem;
    line-height: 1.45;
    color: var(--gn-muted);
}

/* Shown once points have been dragged, so the reader knows a slider will
   rebuild the preset and discard the edit */
.csg-custom-note {
    display: flex;
    gap: 0.4rem;
    padding: 0.4rem 0.6rem;
    margin: 0 0 0.6rem;
    border-radius: 0.4rem;
    background-color: var(--gn-sidebar-hover-bg);
    font-size: 0.75rem;
    color: var(--gn-muted);
}

/* Generated code, always visible - it is the product */
.csg-code {
    max-height: 220px;
    overflow: auto;
    padding: 0.6rem 0.7rem;
    margin: 0.5rem 0 0;
    border: 1px solid var(--gn-card-border);
    border-radius: 0.5rem;
    background-color: var(--gn-sidebar-hover-bg);
    font-size: 0.72rem;
    line-height: 1.45;
    white-space: pre;
    color: var(--gn-body-color);
}

/* On a shape page the code is the thing the reader came for, so it gets a
   card of its own under the tool instead of a scrollbox squeezed into a
   330px panel. Long polygons are readable at the full column width. */
.csg-output {
    margin-top: 1rem;
    border: 1px solid var(--gn-card-border);
    border-radius: 0.75rem;
    overflow: hidden;
}

.csg-output-head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem 0.75rem;
    padding: 0.6rem 0.75rem;
    border-bottom: 1px solid var(--gn-card-border);
}

/* The format switch sits between the title and the copy button */
.csg-output-head .btn-group {
    margin-left: auto;
}

/* .gn-studio-label carries a top margin for stacked panel labels; in a
   centred row it just pushes the title off the buttons' centre line */
.csg-output-head .gn-studio-label {
    margin-top: 0;
}

/* The label changes with the format and again on "Copied!". Measured with
   the fonts loaded, the widest state is "Copy HTML" at 108px, so 7rem
   holds every one of them and the button never twitches. */
.csg-output-head .btn-primary {
    min-width: 7rem;
}

/* The card already supplies the frame.
   The height is pinned at both ends because this card sits above the
   page's own content: without it a format switch moves everything below.
   Measured across all twelve shapes, the code box wants anywhere from
   42px (SVG, one long line) to 476px (the heart as HTML). 13rem covers
   the plain CSS and HTML output of eight of the twelve outright, so their
   card never moves at all, and the cap keeps the worst case to about a
   third of what it was. */
.csg-output .csg-code {
    min-height: 13rem;
    max-height: 340px;
    margin: 0;
    padding: 0.75rem 0.9rem;
    border: 0;
    border-radius: 0;
    font-size: 0.78rem;
}

/* Shape library: a full overlay over the workspace, grouped and searchable */
.csg-browser {
    position: absolute;
    inset: 0;
    z-index: 15;
    display: flex;
    flex-direction: column;
    background-color: var(--gn-card-bg);
}

.csg-browser.d-none {
    display: none;
}

.csg-browser-head {
    display: flex;
    gap: 0.5rem;
    padding: 0.75rem 1rem;
    border-bottom: 1px solid var(--gn-card-border);
}

.csg-browser-body {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    padding: 0 1rem 1rem;
}

.csg-browser-group {
    position: sticky;
    top: 0;
    z-index: 1;
    margin: 0;
    padding: 0.75rem 0 0.4rem;
    background-color: var(--gn-card-bg);
    font-size: 0.72rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--gn-body-color);
}

.csg-browser-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(86px, 1fr));
    gap: 0.5rem;
}

.csg-browser-item {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.35rem;
    padding: 0.5rem 0.25rem;
    border: 1px solid transparent;
    border-radius: 0.5rem;
    background: none;
    color: var(--gn-muted);
    font-size: 0.68rem;
    line-height: 1.2;
    text-align: center;
}

.csg-browser-item:hover,
.csg-browser-item.active {
    border-color: var(--gn-accent);
    color: var(--gn-accent);
}

/* Every tile is the real thing: the same declarations the export emits */
.csg-browser-preview {
    width: 44px;
    height: 44px;
    background-color: var(--gn-accent);
}

.csg-browser-label {
    overflow-wrap: anywhere;
}

/* Variant links in the page copy. They go to the studio rather than to
   another page, so they carry the same glyph as the "Open in the studio"
   button instead of reading as an ordinary cross-reference. The codepoint
   is bi-arrows-fullscreen in Bootstrap Icons 1.13; a class would need a
   wrapper element inside every link. */
.tool-content a[data-shape]::after {
    content: "\F14D";
    display: inline-block;
    margin-left: 0.25em;
    font-family: bootstrap-icons, sans-serif;
    font-size: 0.75em;
    vertical-align: 0.1em;
    text-decoration: none;
}

/* Related shapes at the foot of a shape page */
.csg-related-intro {
    color: var(--gn-muted);
    font-size: 0.9rem;
}

.csg-related {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
    padding: 0;
    margin: 0;
    list-style: none;
}

.csg-related a {
    display: inline-block;
    padding: 0.3rem 0.7rem;
    border: 1px solid var(--gn-card-border);
    border-radius: 2rem;
    font-size: 0.85rem;
    text-decoration: none;
}

.csg-related a:hover {
    border-color: var(--gn-accent);
}

/* The studio is the destination, not another sibling */
.csg-related a.csg-related-studio {
    border-color: var(--gn-accent);
}

@media (max-width: 767px) {
    .csg-inline {
        height: auto;
    }

    /* Stacked into a column, so the fixed 330px above would become a fixed
       HEIGHT. Full width, as tall as its contents. */
    .csg .gn-studio-panel {
        flex: 0 0 auto;
    }

    /* The code box is the point of the tool, so give it room once the
       panel is the full width of the screen */
    .csg-code {
        max-height: 300px;
    }

    /* The title would push the format switch and Copy onto their own
       cramped row; the label is redundant next to a code block anyway */
    .csg-output-head > span {
        display: none;
    }
}
