/* The Analytics area: its period, the tiles, the drawings of
   admin_app/src/View/Charts/ and the parts around them; and Home's last
   30 days, which are drawn the same way. Loaded after layout.css. The
   look is the agreed mocks', docs/mockups/phase-3-analytics.html and
   phase-5-instagram-and-reels.html, built with the admin's own components
   (.card, .table, .btn, .select, .check, .badge, .tag) and tokens, in black,
   white and grey. Colour only where it means something: green and red on
   a change and on vs usual (a hit in a soft green pill), red on what the
   funnel loses, the blues of the ring and the map, the blue of the big
   charts' current period (D101), and the amber of an incomplete
   estimate's triangle (D103).
   Lines are 2 pixels, grid lines hairlines; dashed are only the bucket
   still running, the stretches between two reads of a competitor's reel,
   the usual reel, a marker of a change, the ages marked on a post's
   charts, and a cell of too few reels. Nothing moves. [Phase 3, sections 4.2 to 4.9 and 4.11; Phase 5, section 9]

   Every class starts with an-. The pieces, as the templates put them
   together:

     .an-stack           the blocks of a tab, 20 pixels apart
     .an-grid-2          two blocks side by side from 900 pixels (the
                         heatmap beside "The link")
     .an-seg             a segmented control of links (<nav>), the chosen
                         one .an-seg-item with aria-current: the period of
                         the filter row (components.css, "The filter row",
                         with a button.an-seg-item for dates of one's own,
                         D91, D92), what a card shows
     .an-tiles, .an-tile the tiles, three in a row, or two by two and four
                         in a row from 640 pixels with .an-tiles-4:
                         .an-tile-label (with .an-info, and in a tile that
                         leads somewhere, .an-tile.is-link, its link
                         .an-tile-link), .an-tile-value
                         (.is-muted for a rough estimate, "n/a", "No link"),
                         the change (Figures::changeHtml(): .an-change,
                         .an-up, .an-down, .an-change-vs, kept on a phone
                         with .is-kept, D104), .an-tile-spark
                         around a Sparkline; .an-tile.is-ghost a tile whose
                         figure is not read yet, in the ghost greys [D77]
     .an-info            the (i) button of a definition; .an-term a name
                         that opens one; .an-def the popover itself
                         (Definitions), .an-def-wide one of longer words, a
                         post's caption (M12.5)
     .an-inc             an incomplete estimate's small amber triangle after
                         its number, in a tile at its top-right corner,
                         .an-inc-pop its popover (an .an-def) with
                         .an-inc-word (Triangle; ReelCells::incomplete(),
                         D103; a tile's figure, HeldWords, D104)
     .an-chart-frame     the chart over time (LineChart), its current
                         period in the big charts' blue (.an-line-current,
                         .an-dot-current, .an-legend-key-current, .an-area;
                         D101), a bucket that leads somewhere
                         .an-hit[data-an-href]; .an-legend and its keys
                         .an-legend-key-*, in the frame or on the title's
                         line of its card's header or of .an-chart-head
                         (D101); the bands
                         .an-band-night and .an-band-gap, and the markers
                         .an-mark, .an-mark-bio with its .an-mark-tag,
                         .an-mark-reel and .an-mark-check; .an-chart-named
                         its row for the names of the links set in the
                         bio, .has-lanes with lanes under it, .an-lane, its
                         .an-lane-head, .an-lane-name, .an-lane-x,
                         .an-lane-marks, .an-line-lane, .an-area-lane,
                         .an-dot-lane (D106);
                         .an-chart-bare its bare variant, with
                         .an-area-fade, .an-fade-from and .an-fade-to; in
                         the same frame a post's plays over time
                         (ReelCurveChart: .an-curve-chart, its reads
                         .an-dot-read and .an-dot-halo-read, .an-usual),
                         IG Competitors' reel's (RivalCurveChart: .an-curve,
                         .an-read, .an-posted, .an-chart-over, .an-figure),
                         the ages marked on a chart of a
                         post's age (AgeMarks: .an-age-line,
                         .an-age-line-shown, .an-chart-ages, .an-age-link,
                         .an-age-wide, .an-age-label, .an-age-ring,
                         .an-age-ring-hole;
                         M12.4) and an account's plays and followers
                         (AccountChart: .an-acct, .an-acct-y, .an-acct-plot,
                         .an-acct-title, .an-bar, .an-bar-running)
     .an-hours-frame     a reel's plays and visits per hour
                         (ReelHoursChart): .an-hours-mN, .an-hours-scroll,
                         .an-hours, .an-hours-y, .an-hours-plot,
                         .an-hours-title, .an-bar-other, .an-bar-night,
                         .an-visits-area, .an-credit-area, .an-visits-line,
                         .an-hours-hint
     .an-funnel-frame    the funnel (Funnel); .an-funnel-from-link without
                         the plays; a figure that is a word .an-f-value
                         .is-muted (D104)
     .an-split           the breakdown: .an-split-grid holds the ring
                         (Ring, .an-ring) and .an-table-wrap around a .table
                         whose names carry .an-name with a swatch
                         (Ring::swatch()); .an-split-note under it
     .an-geo             the breakdown by country (WorldMap, D82, D83), whose
                         .an-geo-grid puts .an-geo-map, which holds the map
                         (.an-map: .an-map-land, each .an-map-place, and for
                         a small country .an-map-dot with .an-map-halo and
                         .an-map-mark; .an-map-1 to -5 their blue) and
                         .an-geo-foot (.an-geo-legend with .an-geo-swatch,
                         .an-geo-zoom), beside .an-geo-list, its rows
                         (.an-geo-row, .an-geo-bar, .an-geo-name with
                         .an-geo-key, .an-geo-value, .an-geo-share)
     .an-heat            the heatmap (Heatmap), and when posts do best
                         (PostingTimes: .an-posting, .an-posting-cells,
                         .an-posting-cell, .an-posting-few,
                         .an-posting-legend, .an-posting-scale; .is-ghost
                         the grid before 30 reels, .is-strong its darker
                         cells [D77])
     .an-account, .an-account-icon, .an-row, .an-row-link, .an-group
                         the Accounts tab's table (D83); .an-row.is-unlinked
                         an account without a link in the period, on the
                         muted surface (D115)
     .an-sort            a head that sorts (partials/sort-head.php, D101):
                         .is-sorted, .an-sort-text, .an-sort-sub,
                         .an-sort-idle the chevrons while it does not
     .an-credit          the line under the page naming DB-IP
     .an-live            the Funnel tab's live card (D116): its head
                         (.an-live-head, .an-live-status with the shared .live-dot,
                         .is-paused), .an-live-body of .an-live-main (the
                         figures .an-live-figures on .post-figures, their
                         keys .an-live-key, .an-live-long and -short; the
                         lines .an-live-chart, LineChart's parts) and
                         .an-live-side (.an-live-side-title, .an-live-feed
                         of .an-live-item: .an-live-item-text, -name,
                         -where, -side, -time, -clicked; .is-ghost without
                         a visit, D91; .is-new, .is-moving, .is-leaving
                         while a visit comes in)
     .an-tip             the tooltip analytics.js adds to <body>, or to the
                         record panel that holds what it describes (D76);
                         .an-tip-warn its line with the triangle (D103)
     .an-up, .an-down, .an-pill, .an-none, .an-shaky, .an-empty
                         a change up or down, and vs usual green, red or a
                         hit's soft green pill (Figures::vs(), D101), a figure
                         without a value, a rate from too few visits,
                         nothing to draw

   Container queries rather than media queries wherever the room decides,
   because the sidebar takes as much of it as the window gives. */

/* ------------------------------------------------------------------------
   The page
   ------------------------------------------------------------------------ */

.an-stack {
    display: flex;
    flex-direction: column;
    gap: var(--space-5);
}

.an-grid-2 {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-5);
}

@media (min-width: 900px) {
    .an-grid-2 {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

.an-credit {
    margin-top: 28px;
    color: var(--color-text-subtle);
    font-size: var(--text-xs);
}

.an-credit a {
    color: var(--color-text-muted);
}

.an-up {
    color: var(--color-success-text);
}

.an-down {
    color: var(--color-danger-text);
}

/* vs usual from 3.0x as shown, a hit: a soft green pill (Figures::vs(),
   D101); its colour is .an-up's, and a tile writes the colour alone. */
.an-pill {
    display: inline-block;
    padding: 1px 8px;
    border-radius: var(--radius-full);
    background: var(--color-success-bg);
    color: var(--color-success-text);
    font-weight: var(--weight-semibold);
}

.an-none {
    color: var(--color-text-subtle);
}

/* A rate from fewer than 30 visits: its title says so. */
.an-shaky {
    border-bottom: 1px dotted var(--color-text-subtle);
    cursor: help;
}

.an-empty {
    color: var(--color-text-muted);
}

/* ------------------------------------------------------------------------
   The segmented control
   ------------------------------------------------------------------------ */

/* A segmented control of links: the period, what the chart shows, how the
   breakdown splits. Without script too, as every choice is an address. */
.an-seg {
    display: inline-flex;
    gap: 2px;
    max-width: 100%;
    padding: 3px;
    overflow-x: auto;
    scrollbar-width: none;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    background: var(--color-surface-muted);
}

.an-seg::-webkit-scrollbar {
    display: none;
}

.an-seg-item {
    display: inline-flex;
    align-items: center;
    min-height: 34px;
    padding: 0 var(--space-3);
    /* Concentric with the track: its radius minus its padding. */
    border-radius: calc(var(--radius-sm) - 3px);
    color: var(--color-text-muted);
    font-weight: var(--weight-medium);
    text-decoration: none;
    white-space: nowrap;
}

.an-seg-item:focus-visible {
    outline-offset: -2px;
}

/* The period's item for dates of one's own (D91), a button that opens the
   dates window (D92), looks like the links beside it. */
button.an-seg-item {
    border: 0;
    background: none;
    font: inherit;
    font-weight: var(--weight-medium);
    cursor: pointer;
}

@media (hover: hover) {
    .an-seg-item:hover {
        color: var(--color-text);
    }
}

.an-seg-item[aria-current] {
    background: var(--color-surface-raised);
    color: var(--color-text);
    box-shadow: var(--shadow-sm);
}

/* ------------------------------------------------------------------------
   Definitions: the (i), a name that opens one, and the popover
   ------------------------------------------------------------------------ */

.an-info {
    position: relative;
    display: inline-grid;
    flex: none;
    place-items: center;
    width: 22px;
    height: 22px;
    padding: 0;
    border: 0;
    border-radius: var(--radius-full);
    background: none;
    color: var(--color-text-subtle);
    vertical-align: middle;
}

/* A target of 44 pixels around the small circle. */
.an-info::after {
    content: '';
    position: absolute;
    inset: -11px;
}

.an-info .icon {
    width: 15px;
    height: 15px;
}

@media (hover: hover) {
    .an-info:hover {
        color: var(--color-text);
    }
}

/* A stage's name, underlined with dots as a term with a meaning. */
.an-term {
    align-self: flex-start;
    padding: 0;
    border: 0;
    border-bottom: 1px dotted var(--color-text-subtle);
    background: none;
    color: var(--color-text-muted);
    font-size: 12.5px;
    font-weight: var(--weight-medium);
    line-height: 1.3;
    white-space: nowrap;
    cursor: help;
}

@media (hover: hover) {
    .an-term:hover {
        color: var(--color-text);
    }
}

/* Without script the browser centres the popover; analytics.js places it
   under its button and marks it .is-placed. */
.an-def {
    width: min(300px, calc(100vw - 32px));
    margin: auto;
    padding: var(--space-3) 14px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    background: var(--color-surface);
    color: var(--color-text);
    box-shadow: var(--shadow-lg);
    font-size: var(--text-sm);
}

.an-def.is-placed {
    position: absolute;
    inset: auto;
    margin: 0;
}

/* A popover of longer words, a post's whole caption (M12.5): up to 360
   pixels wide, which analytics.js measures too. */
.an-def-wide {
    width: min(360px, calc(100vw - 32px));
}

.an-def-title {
    font-family: var(--font-sans);
    font-size: var(--text-sm);
    font-weight: var(--weight-semibold);
    letter-spacing: 0;
}

.an-def-text {
    margin-top: var(--space-1);
    color: var(--color-text-muted);
}

/* ------------------------------------------------------------------------
   An incomplete estimate (D103; Phase 5, M7.3): a small amber triangle
   after its number, on its line, drawn like the admin's other icons. Amber
   means a part is missing, for this triangle alone; grey keeps its
   meaning, rough. The triangle hangs in the room after the number, its
   width given back by a negative margin, so a right-aligned number stands
   where the others of its column stand and the column keeps its width: a
   cell's padding of 16 pixels holds the 3 and the 12. Its base sits on
   the number's baseline.
   ------------------------------------------------------------------------ */

.an-inc {
    position: relative;
    display: inline-block;
    width: 12px;
    height: 12px;
    margin: 0 -15px 0 3px;
    padding: 0;
    border: 0;
    border-radius: 2px;
    background: none;
    color: var(--color-warning-text);
    line-height: 0;
    vertical-align: -1px;
}

/* A target of 24 pixels around the small triangle. */
.an-inc::after {
    content: '';
    position: absolute;
    inset: -6px;
}

.an-inc .icon {
    display: block;
    width: 12px;
    height: 12px;
}

@media (hover: hover) {
    .an-inc:hover {
        color: color-mix(in srgb, var(--color-warning-text) 72%, var(--color-text));
    }
}

/* A tile's triangle stands in the tile's top-right corner, on its title's
   line, against its right padding, centred with the title and its (i) as
   the (i) is, and of the (i)'s size, so the two read as a pair; the figure
   stands alone (D104, the developer's look of 22 October 2026). Wherever
   a tile writes it, after its figure, it is placed here, its popover
   opening from it as before. The title keeps clear of it. In a tile that
   leads somewhere it lies over the link, as the (i) does. */
.an-tile {
    position: relative;
}

.an-tile-value .an-inc {
    position: absolute;
    top: calc(var(--space-3) - 3px);
    right: var(--space-3);
    z-index: 1;
    display: inline-grid;
    place-items: center;
    width: 22px;
    height: 22px;
    margin: 0;
    border-radius: var(--radius-full);
    vertical-align: middle;
}

.an-tile-value .an-inc .icon {
    width: 15px;
    height: 15px;
}

.an-tile:has(.an-tile-value .an-inc) .an-tile-label {
    padding-right: 26px;
}

@media (min-width: 640px) {
    .an-tile-value .an-inc {
        top: 11px;
        right: var(--space-4);
    }
}

/* The popover stands in its cell or tile, and takes none of their type:
   not right-aligned or on one line as a cell, not a tile's big figure,
   not a typical row's semibold. One sentence, its first word in the ink. */
.an-inc-pop {
    font-size: var(--text-sm);
    font-weight: var(--weight-normal);
    font-variant-numeric: normal;
    letter-spacing: normal;
    line-height: var(--leading-normal);
    text-align: left;
    white-space: normal;
}

.an-inc-pop .an-def-text {
    margin-top: 0;
}

.an-inc-word {
    color: var(--color-text);
    font-weight: var(--weight-semibold);
}

/* ------------------------------------------------------------------------
   The tiles: the three numbers that matter, each a card of its own, three
   in a row on every width
   ------------------------------------------------------------------------ */

.an-tiles {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--space-2);
}

/* Four tiles: two by two on a phone, four in a row from 640 pixels. */
.an-tiles-4 {
    grid-template-columns: repeat(2, minmax(0, 1fr));
}

.an-tile {
    display: flex;
    flex-direction: column;
    gap: 3px;
    min-width: 0;
    padding: var(--space-3) var(--space-3) 10px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    background: var(--color-surface);
    box-shadow: var(--shadow-xs);
}

.an-tile-label {
    display: flex;
    align-items: flex-start;
    gap: 2px;
    /* Two of its lines, so a title wrapped beside a triangle keeps the
       figures of a row level (D104). */
    min-height: 2.6em;
    color: var(--color-text-muted);
    font-size: 12.5px;
    font-weight: var(--weight-medium);
    line-height: 1.3;
}

.an-tile-label .an-info {
    margin-top: -3px;
}

/* A tile that leads somewhere as a whole (a model's page, D95): its label
   is the link, stretched over the tile, and its (i) stays above it. */
.an-tile.is-link {
    position: relative;
}

.an-tile-link {
    color: inherit;
    text-decoration: none;
}

.an-tile-link::after {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: inherit;
}

.an-tile-link:focus-visible {
    outline: none;
}

.an-tile.is-link:has(.an-tile-link:focus-visible) {
    outline: 2px solid var(--color-focus);
    outline-offset: 2px;
}

.an-tile.is-link .an-info {
    z-index: 1;
}

@media (hover: hover) {
    .an-tile.is-link:hover {
        border-color: var(--color-border-strong);
    }
}

.an-tile-value {
    font-size: clamp(19px, 5.2vw, 28px);
    font-weight: var(--weight-semibold);
    letter-spacing: -0.02em;
    line-height: 1.15;
}

/* A figure that is no plain number: a rough estimate, "n/a", "No link". */
.an-tile-value.is-muted {
    color: var(--color-text-muted);
}

.an-change {
    color: var(--color-text-subtle);
    font-size: var(--text-xs);
    font-weight: var(--weight-medium);
}

.an-change b {
    font-weight: var(--weight-semibold);
}

/* " vs the 30 days before" needs the room of a wider screen. What a
   figure counts from, " since 12 Oct", stays (D104, 5). */
.an-change-vs {
    display: none;
}

.an-change-vs.is-kept,
.side-panel-body .an-change-vs.is-kept {
    display: inline;
}

@media (min-width: 640px) {
    .an-tiles {
        gap: var(--space-4);
    }

    .an-tiles-4 {
        grid-template-columns: repeat(4, minmax(0, 1fr));
    }

    .an-tile {
        padding: 14px var(--space-4) var(--space-3);
    }

    .an-tile-label {
        min-height: 24px;
        font-size: var(--text-sm);
    }

    .an-change-vs {
        display: inline;
    }
}

/* In the record panel (D76) the tiles follow the room in it, the panel's
   body the container "panel" (layout.css): the figures a little smaller
   and the change without its words, four tiles two by two below 720
   pixels of room, and from 920 pixels the wide page's tiles again. */
.side-panel-body .an-tile-value {
    font-size: 24px;
}

.side-panel-body .an-change-vs {
    display: none;
}

@container panel (max-width: 719.98px) {
    .side-panel-body .an-tiles-4 {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

@container panel (min-width: 920px) {
    .side-panel-body .an-tile-value {
        font-size: 28px;
    }

    .side-panel-body .an-change-vs {
        display: inline;
    }
}

/* A tile whose figure is not read yet [D77]: the figure and its change as
   bars of different widths, and at its foot a ghost's line (Ghost::spark()). */
.an-tile.is-ghost .an-tile-value {
    display: flex;
    align-items: center;
    height: 1.15em;
}

.an-tile.is-ghost .an-tile-value .ghost-bar {
    width: 64%;
    height: 16px;
}

.an-tile.is-ghost > .ghost-bar-sm {
    width: 52%;
    margin-top: 5px;
}

.an-tile.is-ghost:nth-child(4n + 2) .an-tile-value .ghost-bar { width: 44%; }
.an-tile.is-ghost:nth-child(4n + 2) > .ghost-bar-sm { width: 46%; }
.an-tile.is-ghost:nth-child(4n + 3) .an-tile-value .ghost-bar { width: 56%; }
.an-tile.is-ghost:nth-child(4n + 3) > .ghost-bar-sm { width: 58%; }
.an-tile.is-ghost:nth-child(4n) .an-tile-value .ghost-bar { width: 50%; }
.an-tile.is-ghost:nth-child(4n) > .ghost-bar-sm { width: 40%; }

.an-tile.is-ghost .an-tile-spark svg {
    display: block;
    width: 100%;
    height: 100%;
    overflow: visible;
}

/* The line of a tile at its foot (Sparkline): the period in the grey of
   the period before, ending in a dark point with a ring of the card's
   colour. Its strokes do not scale with the box. */
.an-tile-spark {
    height: 28px;
    margin-top: var(--space-1);
}

@media (min-width: 640px) {
    .an-tile-spark {
        height: 30px;
    }
}

.an-spark {
    display: block;
    width: 100%;
    height: 100%;
    overflow: visible;
}

.an-spark-line {
    fill: none;
    stroke: var(--color-chart-prev);
    stroke-width: 1.5;
    stroke-linejoin: round;
    stroke-linecap: round;
    vector-effect: non-scaling-stroke;
}

.an-spark-halo,
.an-spark-point {
    stroke-linecap: round;
    vector-effect: non-scaling-stroke;
}

.an-spark-halo {
    stroke: var(--color-surface);
    stroke-width: 10;
}

.an-spark-point {
    stroke: var(--color-chart-ink);
    stroke-width: 6;
}

/* ------------------------------------------------------------------------
   The chart over time (LineChart). The frame is the container its queries
   ask: from 520 pixels the chart is taller and an hourly axis names more
   hours; by day, the axis names as many days as fit one per 90 pixels,
   in the bands of LineChart::BANDS.
   ------------------------------------------------------------------------ */

.an-chart-frame {
    container: an-chart / inline-size;
}

.an-legend {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-1) var(--space-4);
    color: var(--color-text-muted);
    font-size: var(--text-xs);
}

.an-legend-item {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

/* A chart's legend on its title's line (D101): on the right, and under the
   title where the line is too short. In a card's header, beside its
   .card-title (each drawing's legend(), its render() told
   'legendInHeader'), whose title takes 20rem before the legend wraps
   (components.css); over a chart inside a card, beside its sub-title, in
   .an-chart-head. A bare chart has none. */
.card-header:has(> .an-legend) {
    align-items: baseline;
}

.an-chart-head {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: 0 var(--space-4);
}

.an-legend-key {
    display: inline-block;
    width: 14px;
    height: 2px;
    border-radius: 1px;
    background: var(--color-chart-ink);
}

.an-legend-key-prev {
    background: var(--color-chart-prev);
}

/* The current period of LineChart, in the blue of the big charts (D101). */
.an-legend-key-current {
    background: var(--color-chart-line);
}

/* The keys of the reads of Instagram and of the markers (Phase 5, sections
   9.1 to 9.5): a dot, a line between two reads, the usual reel, squares for
   bars and areas and bands, a ring for a change and a tick for a reel. */
.an-legend-key-dot {
    width: 8px;
    height: 8px;
    border-radius: var(--radius-full);
}

.an-legend-key-dash,
.an-legend-key-usual {
    height: 0;
    border-top: 2px dashed var(--color-chart-ink);
    border-radius: 0;
    background: none;
}

.an-legend-key-usual {
    border-top-color: var(--color-chart-prev);
}

.an-legend-key-bar,
.an-legend-key-other,
.an-legend-key-visits,
.an-legend-key-credit {
    width: 10px;
    height: 10px;
    border-radius: 2px;
}

.an-legend-key-other {
    background: var(--color-chart-other);
}

.an-legend-key-visits {
    border-top: 2px solid var(--color-text-subtle);
    background: var(--color-chart-visits);
}

.an-legend-key-credit {
    opacity: 0.85;
}

.an-legend-key-gap,
.an-legend-key-night {
    width: 12px;
    height: 12px;
    border-radius: 2px;
    background: var(--color-chart-gap);
}

.an-legend-key-night {
    border: 1px solid var(--color-border);
    background: var(--color-chart-night);
}

.an-legend-key-change {
    width: 7px;
    height: 7px;
    border: 1px solid var(--color-chart-prev);
    border-radius: var(--radius-full);
    background: var(--color-surface);
}

.an-legend-key-reel {
    width: 2px;
    height: 8px;
    border-radius: 1px;
    background: var(--color-text-subtle);
}

.an-legend-key-check {
    width: 5px;
    height: 5px;
    border-radius: var(--radius-full);
    background: var(--color-chart-prev);
}

.an-chart {
    position: relative;
    height: 200px;
    margin-top: var(--space-3);
}

/* The margins of the plot, the mock's: 44 pixels for the values on the
   left, 8 on the right, 24 above for the markers, 26 below for the times.
   The curve of a reel (ReelCurveChart) has the same. */
.an-chart-y {
    position: absolute;
    top: 24px;
    bottom: 26px;
    left: 0;
    width: 36px;
}

.an-y {
    position: absolute;
    right: 0;
    color: var(--color-text-subtle);
    font-size: 11px;
    font-variant-numeric: tabular-nums;
    line-height: 1;
    white-space: nowrap;
    transform: translateY(-50%);
}

.an-y-0 { top: 100%; }
.an-y-1 { top: 75%; }
.an-y-2 { top: 50%; }
.an-y-3 { top: 25%; }
.an-y-4 { top: 0; }

.an-chart-plot {
    position: absolute;
    top: 24px;
    left: 44px;
    width: calc(100% - 52px);
    max-width: none;
    height: calc(100% - 50px);
    overflow: visible;
    /* A finger moving across the chart moves the crosshair; up and down it
       still scrolls the page. */
    touch-action: pan-y;
}

.an-grid-line {
    stroke: var(--color-chart-grid);
    stroke-width: 1;
    vector-effect: non-scaling-stroke;
}

/* Behind the lines and bars: the night pause light, a stretch without
   reads grey (Phase 5, section 1.7). */
.an-band-night {
    fill: var(--color-chart-night);
}

.an-band-gap {
    fill: var(--color-chart-gap);
}

/* LineChart's area under the current period, in the blue's wash (D101). */
.an-area {
    fill: var(--color-chart-line-wash);
}

.an-line {
    fill: none;
    stroke: var(--color-chart-ink);
    stroke-width: 2;
    stroke-linejoin: round;
    stroke-linecap: round;
    vector-effect: non-scaling-stroke;
}

.an-line-prev {
    stroke: var(--color-chart-prev);
}

/* The current period of LineChart in a card, the Instagram tab's chart, in
   one blue; the Dashboard's bare chart and every other drawing keep the
   ink (D101). */
.an-line-current {
    stroke: var(--color-chart-line);
}

/* The bucket still running. */
.an-line-running {
    stroke-dasharray: 3 4;
}

.an-dot-halo,
.an-dot {
    stroke-linecap: round;
    vector-effect: non-scaling-stroke;
}

.an-dot-halo {
    stroke: var(--color-surface);
    stroke-width: 10;
}

.an-dot {
    stroke: var(--color-chart-ink);
    stroke-width: 6;
}

.an-dot-prev {
    stroke: var(--color-chart-prev);
}

.an-dot-current {
    stroke: var(--color-chart-line);
}

.an-xhair {
    visibility: hidden;
    pointer-events: none;
}

.is-pointing .an-xhair {
    visibility: visible;
}

.an-xhair-line {
    stroke: var(--color-text-subtle);
    stroke-width: 1;
    vector-effect: non-scaling-stroke;
}

.an-hit {
    fill: transparent;
}

/* A bucket that leads somewhere, the reels it lists: analytics.js follows
   its data-an-href on a click, on a touch screen at the second tap. */
.an-hit[data-an-href] {
    cursor: pointer;
}

.an-chart-x,
.an-chart-marks {
    position: absolute;
    left: 44px;
    width: calc(100% - 52px);
    max-width: none;
    overflow: visible;
}

.an-chart-x {
    bottom: 0;
    height: 26px;
}

.an-x-label {
    display: none;
    fill: var(--color-text-subtle);
    font-family: var(--font-sans);
    font-size: 11px;
    font-variant-numeric: tabular-nums;
}

/* An axis whose labels show at every width. */
.an-x-all {
    display: inline;
}

.an-chart-marks {
    top: 0;
    height: calc(100% - 26px);
    pointer-events: none;
}

.an-mark {
    overflow: visible;
}

/* A marker is thin and light, without text (Phase 5, section 9.1): a
   change a dashed hairline under a small ring, a reel posted a short tick
   at the foot of the plays, a check by Meta a small dot in the ring's place
   above the plot, which fills the ring of a change in the same bucket
   (D85). Its name shows on hover, on tap and on keyboard focus, which
   outlines its target. */
.an-mark-line {
    stroke: var(--color-border-strong);
    stroke-width: 1;
    stroke-dasharray: 2 3;
}

.an-mark-ring {
    fill: var(--color-surface);
    stroke: var(--color-chart-prev);
    stroke-width: 1;
}

.an-mark-tick {
    stroke: var(--color-text-subtle);
    stroke-width: 1.5;
    stroke-linecap: round;
}

.an-mark-dot {
    fill: var(--color-chart-prev);
}

.an-mark-hit {
    fill: transparent;
    pointer-events: all;
    outline: none;
}

.an-mark-hit:focus-visible {
    stroke: var(--color-focus);
    stroke-width: 2;
}

@container an-chart (min-width: 520px) {
    .an-chart {
        height: 240px;
    }

    .an-x-wide {
        display: inline;
    }
}

@container an-chart (max-width: 519.98px) {
    .an-x-narrow {
        display: inline;
    }
}

/* The bands of LineChart::BANDS: .an-wN names the days of the band N. */
@container an-chart (max-width: 313.98px) {
    .an-w2 { display: inline; }
}

@container an-chart (min-width: 314px) and (max-width: 403.98px) {
    .an-w3 { display: inline; }
}

@container an-chart (min-width: 404px) and (max-width: 493.98px) {
    .an-w4 { display: inline; }
}

@container an-chart (min-width: 494px) and (max-width: 583.98px) {
    .an-w5 { display: inline; }
}

@container an-chart (min-width: 584px) and (max-width: 673.98px) {
    .an-w6 { display: inline; }
}

@container an-chart (min-width: 674px) and (max-width: 763.98px) {
    .an-w7 { display: inline; }
}

@container an-chart (min-width: 764px) and (max-width: 853.98px) {
    .an-w8 { display: inline; }
}

@container an-chart (min-width: 854px) and (max-width: 943.98px) {
    .an-w9 { display: inline; }
}

@container an-chart (min-width: 944px) and (max-width: 1033.98px) {
    .an-w10 { display: inline; }
}

@container an-chart (min-width: 1034px) {
    .an-w11 { display: inline; }
}

/* A link set in the bio named on its line (D106): a row of 18 pixels more
   above the plot holds "Link in bio" beside its ring, so the words never
   sit on the lines. Its ring and line a step stronger than a change's. */
.an-chart-named {
    height: 218px;
}

.an-chart-named .an-chart-y,
.an-chart-named .an-chart-plot {
    top: 42px;
}

.an-chart-named .an-chart-plot {
    height: calc(100% - 68px);
}

.an-mark-tag {
    fill: var(--color-text-muted);
    font-family: var(--font-sans);
    font-size: 11px;
    font-weight: var(--weight-medium);
    pointer-events: none;
}

.an-mark-bio .an-mark-ring {
    stroke: var(--color-text-subtle);
}

.an-mark-bio .an-mark-line {
    stroke: var(--color-text-subtle);
}

/* Lanes under the chart (D106): each figure on a scale of its own, the
   same times across, its name and its x above it, its line in the chart's
   blue over its wash, the current period as the chart's. The chart above
   them keeps 8 pixels below its plot; the time axis stands under the last
   lane. A lane names the top and the bottom of its scale alone, and draws
   their lines alone, so the lanes stay calm. */
.an-chart.has-lanes {
    height: 182px;
}

.an-chart.has-lanes .an-chart-y {
    bottom: 8px;
}

.an-chart.has-lanes .an-chart-plot {
    height: calc(100% - 32px);
}

.an-chart.has-lanes .an-chart-marks {
    height: calc(100% - 8px);
}

.an-chart-named.has-lanes {
    height: 200px;
}

.an-chart-named.has-lanes .an-chart-plot {
    height: calc(100% - 50px);
}

.an-chart.an-lane {
    height: 104px;
    margin-top: var(--space-2);
}

.an-chart.an-lane.is-last {
    height: 122px;
}

.an-lane .an-chart-y {
    top: 30px;
    bottom: 8px;
}

.an-lane.is-last .an-chart-y {
    bottom: 26px;
}

.an-lane .an-chart-plot {
    top: 30px;
    height: calc(100% - 38px);
}

.an-lane.is-last .an-chart-plot {
    height: calc(100% - 56px);
}

.an-lane .an-y-1,
.an-lane .an-y-2,
.an-lane .an-y-3 {
    display: none;
}

.an-lane-head {
    position: absolute;
    top: 0;
    right: 8px;
    left: 44px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-2);
    height: 26px;
}

.an-lane-name {
    overflow: hidden;
    color: var(--color-text-muted);
    font-size: var(--text-xs);
    font-weight: var(--weight-medium);
    text-overflow: ellipsis;
    white-space: nowrap;
}

.an-lane-x {
    display: inline-flex;
    flex: none;
    align-items: center;
    justify-content: center;
    width: 24px;
    height: 24px;
    margin-right: -6px;
    border-radius: var(--radius-sm);
    color: var(--color-text-subtle);
}

.an-lane-x .icon {
    width: 14px;
    height: 14px;
}

@media (hover: hover) {
    .an-lane-x:hover {
        background: var(--color-surface-hover);
        color: var(--color-text);
    }
}

.an-lane-marks {
    position: absolute;
    top: 30px;
    left: 44px;
    width: calc(100% - 52px);
    max-width: none;
    height: calc(100% - 38px);
    overflow: visible;
    pointer-events: none;
}

.an-lane.is-last .an-lane-marks {
    height: calc(100% - 56px);
}

.an-lane-marks .an-mark-line {
    stroke: var(--color-border-strong);
}

.an-line-lane {
    stroke: var(--color-chart-line);
    stroke-width: 1.5;
}

.an-area-lane {
    fill: var(--color-chart-line-wash);
}

.an-dot-lane {
    stroke: var(--color-chart-line);
    stroke-width: 5;
}

/* A check by Meta on the Instagram tab's chart in Instagram's colour, the
   platform whose links Meta checks there, a little larger, so a check
   stands out from the reels' ticks; its tooltip says how far it went
   (D106). A check is ordinary: no colour of alarm. The checks of an
   account's page keep their grey. */
.rl-chart-card .an-mark-dot {
    fill: var(--color-platform-instagram);
    r: 3px;
}

.rl-chart-card .an-legend-key-check {
    width: 6px;
    height: 6px;
    background: var(--color-platform-instagram);
}

/* On a narrow chart the first link set in the bio alone is named; the
   others keep their line, ring and tooltip (D106). */
@container an-chart (max-width: 519.98px) {
    .an-mark-bio ~ .an-mark-bio .an-mark-tag {
        display: none;
    }
}

@container an-chart (min-width: 520px) {
    .an-chart-named {
        height: 258px;
    }

    .an-chart.has-lanes {
        height: 222px;
    }

    .an-chart-named.has-lanes {
        height: 240px;
    }

    .an-chart.an-lane {
        height: 112px;
    }

    .an-chart.an-lane.is-last {
        height: 130px;
    }
}

/* The bare chart, Home's (D75): no value axis, so the plot runs from edge
   to edge of its card's content; the end point's ring reaches into the
   card's padding. A little room above the plot for the crosshair's point
   at the top. */
.an-chart-bare {
    height: 200px;
    margin-top: 0;
}

.an-chart-bare .an-chart-plot,
.an-chart-bare .an-chart-x {
    left: 0;
    width: 100%;
}

.an-chart-bare .an-chart-plot {
    top: 8px;
    height: calc(100% - 34px);
}

.an-area-fade {
    fill: url(#an-chart-fade);
}

.an-fade-from,
.an-fade-to {
    stop-color: var(--color-chart-fade);
}

/* Down to nothing at the baseline, a soft area under the line. By day
   the usual days stand well up the plot, even beside one busy day, so
   they keep their share of the tint; by hour, one spike would leave the
   usual hours almost none. */
.an-fade-to {
    stop-opacity: 0;
}

@container an-chart (min-width: 520px) {
    .an-chart-bare {
        height: 260px;
    }
}

/* ------------------------------------------------------------------------
   A reel's plays over time, in LineChart's frame and margins. On a post's
   page (ReelCurveChart, M12.4) the line is solid in the blue of the chart's
   current period over its wash (.an-line-current, .an-area), its reads
   the blue points (.an-dot-current) smaller than the end of LineChart's
   line (.an-dot-read, its halo .an-dot-halo-read), its lanes LineChart's.
   On IG Competitors' reel (RivalCurveChart) a dashed line between two
   reads (.an-curve), a dot at each read, an open circle at the posting,
   the read at 3 days larger with its figure: only the reads are measured.
   Both draw the account's usual reel faint and dashed in the grey of the
   period before. [Phase 5, sections 3.1 and 9.3, M5.8]
   ------------------------------------------------------------------------ */

.an-dot-read {
    stroke-width: 5.5;
}

.an-dot-halo-read {
    stroke-width: 8.5;
}

.an-curve {
    fill: none;
    stroke: var(--color-chart-ink);
    stroke-width: 1.6;
    stroke-dasharray: 3 3;
    stroke-linejoin: round;
    vector-effect: non-scaling-stroke;
}

.an-usual {
    fill: none;
    stroke: var(--color-chart-prev);
    stroke-width: 1.5;
    stroke-dasharray: 6 4;
    stroke-linejoin: round;
    vector-effect: non-scaling-stroke;
}

/* The ages marked on a chart of a post's age (AgeMarks; Phase 5, M12.4
   and M12.9): a dotted line in the grey of the period before for each, the
   age shown solid in ink, never a line's blue, and the labels over the plot
   in the 24 pixels above it, each a link; on a chart that names a link set
   in the bio, in the row under its words. The ring where the line meets the
   age shown: the surface in the blue's stroke of 2.5 pixels, radius 5. */
.an-age-line,
.an-age-line-shown {
    vector-effect: non-scaling-stroke;
}

.an-age-line {
    stroke: var(--color-chart-prev);
    stroke-width: 1;
    stroke-dasharray: 2 3;
}

.an-age-line-shown {
    stroke: var(--color-chart-ink);
    stroke-width: 1.25;
}

.an-chart-ages {
    position: absolute;
    top: 0;
    left: 44px;
    width: calc(100% - 52px);
    max-width: none;
    height: 24px;
    overflow: visible;
}

.an-chart-named .an-chart-ages {
    top: 18px;
}

.an-age-link {
    outline: none;
    text-decoration: none;
}

@container an-chart (max-width: 519.98px) {
    .an-age-wide {
        display: none;
    }
}

.an-age-label {
    fill: var(--color-text-subtle);
    font-family: var(--font-sans);
    font-size: 11px;
    font-weight: var(--weight-medium);
    font-variant-numeric: tabular-nums;
}

.an-age-label.is-shown {
    fill: var(--color-text);
    font-weight: var(--weight-semibold);
}

@media (hover: hover) {
    .an-age-link:hover .an-age-label {
        fill: var(--color-text);
    }
}

.an-age-link:focus-visible .an-age-label {
    fill: var(--color-text);
    text-decoration: underline;
    text-decoration-color: var(--color-focus);
    text-decoration-thickness: 2px;
    text-underline-offset: 3px;
}

.an-age-ring,
.an-age-ring-hole {
    stroke-linecap: round;
    vector-effect: non-scaling-stroke;
}

.an-age-ring {
    stroke: var(--color-chart-line);
    stroke-width: 12.5;
}

.an-age-ring-hole {
    stroke: var(--color-surface);
    stroke-width: 7.5;
}

.an-read,
.an-posted,
.an-posted-hole {
    stroke-linecap: round;
    vector-effect: non-scaling-stroke;
}

.an-read {
    stroke: var(--color-chart-ink);
    stroke-width: 5.2;
}

/* The open circle: a ring of ink 1.5 pixels wide round the card's colour. */
.an-posted {
    stroke: var(--color-chart-ink);
    stroke-width: 7;
}

.an-posted-hole {
    stroke: var(--color-surface);
    stroke-width: 4;
}

.an-dot-halo-end {
    stroke-width: 13;
}

.an-dot-end {
    stroke-width: 9;
}

/* Text over the plot, which must not stretch with it: the last read's
   figure. */
.an-chart-over {
    position: absolute;
    top: 24px;
    left: 44px;
    width: calc(100% - 52px);
    max-width: none;
    height: calc(100% - 50px);
    overflow: visible;
    pointer-events: none;
}

.an-figure {
    fill: var(--color-text);
    font-family: var(--font-sans);
    font-size: var(--text-xs);
    font-weight: var(--weight-semibold);
    font-variant-numeric: tabular-nums;
}

/* ------------------------------------------------------------------------
   A reel's plays and visits per hour (ReelHoursChart): two panels on one
   time line, 10 pixels above the plot, 150 for the plays, 30 for the
   visits' title, 110 for the visits and 26 for the times. Each hour takes
   at least 9 pixels: narrower than the drawing's minimum width, which its
   frame names by the hours it has in steps of 12 (.an-hours-m12 to
   .an-hours-m72, ReelHoursChart::minWidth()), it scrolls sideways inside
   its card, reaching to the card's edges, fades at them, and says so under
   it, as the funnel does. The frame is the container its queries ask.
   [Phase 5, sections 3.6 and 9.3]
   ------------------------------------------------------------------------ */

.an-hours-frame {
    container: an-hours / inline-size;
}

.an-hours-scroll {
    margin: var(--space-3) calc(-1 * var(--space-5)) 0;
    padding: 0 var(--space-5);
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scrollbar-width: none;
}

.an-hours-scroll::-webkit-scrollbar {
    display: none;
}

@media (min-width: 640px) {
    .an-hours-scroll {
        margin: var(--space-3) calc(-1 * var(--space-6)) 0;
        padding: 0 var(--space-6);
    }
}

.an-hours {
    position: relative;
    height: 326px;
}

.an-hours-m12 .an-hours { min-width: 160px; }
.an-hours-m24 .an-hours { min-width: 268px; }
.an-hours-m36 .an-hours { min-width: 376px; }
.an-hours-m48 .an-hours { min-width: 484px; }
.an-hours-m60 .an-hours { min-width: 592px; }
.an-hours-m72 .an-hours { min-width: 700px; }

.an-hours-y {
    position: absolute;
    top: 10px;
    left: 0;
    width: 36px;
    height: 290px;
}

.an-hy-plays-top { top: 0; }
.an-hy-plays-0 { top: 150px; }
.an-hy-visits-top { top: 180px; }
.an-hy-visits-0 { top: 100%; }

.an-hours-plot {
    position: absolute;
    top: 10px;
    left: 44px;
    width: calc(100% - 52px);
    max-width: none;
    height: 290px;
    overflow: visible;
}

/* The second panel's title and the followers', in the room between the
   panels. */
.an-hours-title,
.an-acct-title {
    position: absolute;
    left: 44px;
    color: var(--color-text-muted);
    font-size: var(--text-xs);
    font-weight: var(--weight-medium);
    line-height: 1;
    white-space: nowrap;
}

.an-hours-title {
    top: 168px;
}

.an-bar {
    fill: var(--color-chart-ink);
}

.an-bar-other {
    fill: var(--color-chart-other);
}

/* An hour of the night pause, its plays estimated between two reads. */
.an-bar-night {
    opacity: 0.45;
}

.an-visits-area {
    fill: var(--color-chart-visits);
}

.an-credit-area {
    fill: var(--color-chart-ink);
    opacity: 0.85;
}

.an-visits-line {
    fill: none;
    stroke: var(--color-text-subtle);
    stroke-width: 1.5;
    stroke-linejoin: round;
    vector-effect: non-scaling-stroke;
}

.an-hours-hint {
    display: none;
    margin-top: 6px;
    color: var(--color-text-subtle);
    font-size: var(--text-xs);
    text-align: center;
}

@container an-hours (max-width: 159.98px) {
    .an-hours-m12 .an-hours-scroll {
        -webkit-mask-image: linear-gradient(to right, transparent 0, black 16px, black calc(100% - 16px), transparent 100%);
        mask-image: linear-gradient(to right, transparent 0, black 16px, black calc(100% - 16px), transparent 100%);
    }

    .an-hours-m12 .an-hours-hint {
        display: block;
    }
}

@container an-hours (max-width: 267.98px) {
    .an-hours-m24 .an-hours-scroll {
        -webkit-mask-image: linear-gradient(to right, transparent 0, black 16px, black calc(100% - 16px), transparent 100%);
        mask-image: linear-gradient(to right, transparent 0, black 16px, black calc(100% - 16px), transparent 100%);
    }

    .an-hours-m24 .an-hours-hint {
        display: block;
    }
}

@container an-hours (max-width: 375.98px) {
    .an-hours-m36 .an-hours-scroll {
        -webkit-mask-image: linear-gradient(to right, transparent 0, black 16px, black calc(100% - 16px), transparent 100%);
        mask-image: linear-gradient(to right, transparent 0, black 16px, black calc(100% - 16px), transparent 100%);
    }

    .an-hours-m36 .an-hours-hint {
        display: block;
    }
}

@container an-hours (max-width: 483.98px) {
    .an-hours-m48 .an-hours-scroll {
        -webkit-mask-image: linear-gradient(to right, transparent 0, black 16px, black calc(100% - 16px), transparent 100%);
        mask-image: linear-gradient(to right, transparent 0, black 16px, black calc(100% - 16px), transparent 100%);
    }

    .an-hours-m48 .an-hours-hint {
        display: block;
    }
}

@container an-hours (max-width: 591.98px) {
    .an-hours-m60 .an-hours-scroll {
        -webkit-mask-image: linear-gradient(to right, transparent 0, black 16px, black calc(100% - 16px), transparent 100%);
        mask-image: linear-gradient(to right, transparent 0, black 16px, black calc(100% - 16px), transparent 100%);
    }

    .an-hours-m60 .an-hours-hint {
        display: block;
    }
}

@container an-hours (max-width: 699.98px) {
    .an-hours-m72 .an-hours-scroll {
        -webkit-mask-image: linear-gradient(to right, transparent 0, black 16px, black calc(100% - 16px), transparent 100%);
        mask-image: linear-gradient(to right, transparent 0, black 16px, black calc(100% - 16px), transparent 100%);
    }

    .an-hours-m72 .an-hours-hint {
        display: block;
    }
}

/* ------------------------------------------------------------------------
   An account's plays and followers (AccountChart), in LineChart's frame,
   margins and bands of width: 14 pixels above the plot for the markers'
   rings, 140 for the plays, 34 for the followers' title, 80 for the
   followers and 26 for the times; the markers' layer is LineChart's.
   [Phase 5, section 9.5]
   ------------------------------------------------------------------------ */

.an-acct {
    position: relative;
    height: 294px;
    margin-top: var(--space-3);
}

.an-acct-y {
    position: absolute;
    top: 14px;
    left: 0;
    width: 36px;
    height: 254px;
}

.an-ay-plays-top { top: 0; }
.an-ay-plays-mid { top: 70px; }
.an-ay-plays-0 { top: 140px; }
.an-ay-followers-top { top: 174px; }
.an-ay-followers-0 { top: 100%; }

.an-acct-plot {
    position: absolute;
    top: 14px;
    left: 44px;
    width: calc(100% - 52px);
    max-width: none;
    height: 254px;
    overflow: visible;
    touch-action: pan-y;
}

.an-acct-title {
    top: 166px;
}

/* The bucket still running. */
.an-bar-running {
    opacity: 0.4;
}

/* ------------------------------------------------------------------------
   The funnel (Funnel): one drawing on every screen. Narrower than its
   minimum width, it scrolls sideways inside its card, reaching to the
   card's edges, fades at them, and says so under it. From a card of 900
   pixels the band grows, as in the mock. The numbers here mirror
   Funnel::STAGES, MIN_WIDTH, MIN_WIDTH_FROM_LINK, BAND and DEPTH: the
   stages' heads stand at the fractions of the live part the flows are
   drawn at, the flows start 78 pixels down, under the heads, and are DEPTH
   tall, or DEPTH times 168 / 146 on the wider card. The plays take the
   150 pixels left of the live part at every width; without them
   (.an-funnel-from-link) the live part starts at the left edge and the
   minimum width is 598 pixels.
   ------------------------------------------------------------------------ */

.an-funnel-frame {
    container: an-funnel / inline-size;
}

.an-funnel-scroll {
    margin: 0 calc(-1 * var(--space-5));
    padding: 0 var(--space-5);
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scrollbar-width: none;
}

.an-funnel-scroll::-webkit-scrollbar {
    display: none;
}

@media (min-width: 640px) {
    .an-funnel-scroll {
        margin: 0 calc(-1 * var(--space-6));
        padding: 0 var(--space-6);
    }
}

.an-funnel {
    position: relative;
    min-width: 748px;
}

/* The drawing's height, an empty SVG for each band (Funnel::size()). */
.an-f-size {
    display: block;
}

.an-f-size-wide {
    display: none;
}

.an-funnel-hint {
    display: none;
    margin-top: 6px;
    color: var(--color-text-subtle);
    font-size: var(--text-xs);
    text-align: center;
}

/* A mask reads only how opaque its colours are: black here is no colour
   of the interface. */
@container an-funnel (max-width: 747.98px) {
    .an-funnel-scroll {
        -webkit-mask-image: linear-gradient(to right, transparent 0, black 16px, black calc(100% - 16px), transparent 100%);
        mask-image: linear-gradient(to right, transparent 0, black 16px, black calc(100% - 16px), transparent 100%);
    }

    .an-funnel-hint {
        display: block;
    }
}

.an-funnel-from-link .an-funnel {
    min-width: 598px;
}

@container an-funnel (min-width: 598px) {
    .an-funnel-from-link .an-funnel-scroll {
        -webkit-mask-image: none;
        mask-image: none;
    }

    .an-funnel-from-link .an-funnel-hint {
        display: none;
    }
}

/* The live part: 150 pixels for the plays on the left, their head's room,
   and on the right the last bar's 8. */
.an-f-area {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 150px;
    right: 8px;
}

.an-funnel-from-link .an-f-area {
    left: 0;
}

/* The plays (Phase 5, section 9.4): their head at the left edge, their bar
   and its break and note in .an-f-pover, their flow into the first stage
   in .an-f-pflow, from the bar's 8 pixels to the live part. */
.an-f-head-plays {
    left: 0;
}

.an-f-pflow,
.an-f-pover {
    position: absolute;
    top: 78px;
    max-width: none;
    height: 180px;
    overflow: visible;
}

.an-f-pflow {
    left: 8px;
    width: 142px;
}

.an-f-pover {
    left: 0;
    width: 8px;
    pointer-events: none;
}

.an-f-break {
    fill: none;
    stroke: var(--color-surface);
    stroke-width: 2.5;
}

.an-f-note {
    fill: var(--color-text-subtle);
    font-family: var(--font-sans);
    font-size: 10.5px;
}

.an-f-flows,
.an-f-over {
    position: absolute;
    top: 78px;
    left: 0;
    width: 100%;
    max-width: none;
    height: 180px;
    overflow: visible;
}

.an-f-over {
    pointer-events: none;
}

.an-f-flow {
    fill: var(--color-chart-flow);
}

/* What falls away fades from the ink to nothing. */
.an-f-fall {
    fill: url(#an-f-fade);
}

.an-f-fade-from {
    stop-color: var(--color-chart-ink);
    stop-opacity: 0.16;
}

.an-f-fade-to {
    stop-color: var(--color-chart-ink);
    stop-opacity: 0;
}

.an-f-hit {
    fill: transparent;
    cursor: help;
}

.an-f-bar {
    fill: var(--color-chart-ink);
}

/* The browser's band named on it, with the (i) of its definition
   (Funnel::band()): between In an app and Made it out, 8 pixels after the
   middle, as the mock sets the name. The empty SVG before it reaches half
   the band, and the line is centred there. Only its (i) takes the pointer,
   so the band under it keeps its tooltip. */
.an-f-band {
    position: absolute;
    top: 78px;
    left: calc(31.475% + 8px);
    display: flex;
    flex-direction: column;
    height: 180px;
    pointer-events: none;
}

.an-f-band > * {
    flex: none;
}

.an-f-band .an-info {
    pointer-events: auto;
}

.an-f-band-line {
    display: flex;
    align-items: center;
    transform: translate(-50%, -50%);
    white-space: nowrap;
}

.an-f-band-label {
    color: var(--color-text-muted);
    font-size: 11px;
    line-height: 1;
}

.an-f-head {
    position: absolute;
    top: 0;
    display: flex;
    flex-direction: column;
    gap: 1px;
}

.an-f-head-0 { left: 0; }
.an-f-head-1 { left: 22.2%; }
.an-f-head-2 { left: 40.75%; }
.an-f-head-3 { left: 62.25%; }

/* The last head ends where the last bar does. */
.an-f-head-4 {
    right: -8px;
    align-items: flex-end;
    text-align: right;
}

.an-f-head-4 .an-term {
    align-self: flex-end;
}

.an-f-value {
    font-size: var(--text-xl);
    font-weight: var(--weight-semibold);
    letter-spacing: -0.02em;
    line-height: 1.2;
}

.an-f-share {
    color: var(--color-text-subtle);
    font-size: var(--text-xs);
    white-space: nowrap;
}

/* A stage whose figure is a word: "No link" (D104, 1). */
.an-f-value.is-muted {
    color: var(--color-text-muted);
}

/* A loss's label, 16 pixels after its stage's bar and, through the empty
   SVG before it, under the end of its fall. Only its (i) takes the pointer,
   so the band under the box keeps its tooltip. */
.an-f-drop {
    position: absolute;
    top: 78px;
    display: flex;
    flex-direction: column;
    height: 180px;
    font-size: var(--text-xs);
    line-height: 1.4;
    white-space: nowrap;
    pointer-events: none;
}

.an-f-drop > * {
    flex: none;
}

.an-f-drop .an-info {
    pointer-events: auto;
}

.an-f-drop-stuck {
    left: calc(22.2% + 16px);
}

.an-f-drop-left {
    left: calc(62.25% + 16px);
}

.an-f-spacer {
    display: block;
}

.an-f-drop-line {
    display: flex;
    align-items: center;
    gap: var(--space-1);
    color: var(--color-text-muted);
}

.an-f-drop-line b {
    color: var(--color-danger-text);
    font-size: var(--text-sm);
    font-weight: var(--weight-semibold);
}

.an-f-drop-share {
    color: var(--color-text-subtle);
    font-size: 11.5px;
}

/* The wider card: a band of 168 pixels; the plays keep their 150 pixels,
   so the live part is at least as wide as at the minimum width. */
@container an-funnel (min-width: 900px) {
    .an-f-size-narrow {
        display: none;
    }

    .an-f-size-wide {
        display: block;
    }

    .an-f-flows,
    .an-f-over,
    .an-f-drop,
    .an-f-band {
        height: 207.12px;
    }

    .an-f-pflow,
    .an-f-pover {
        height: 207.12px;
    }
}

/* ------------------------------------------------------------------------
   The breakdown: the ring beside its table, under it on a phone
   ------------------------------------------------------------------------ */

.an-split {
    container: an-split / inline-size;
}

.an-split-grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-5);
    align-items: center;
}

/* Beside the ring from 54rem: its table then has the 40rem its four
   columns need. Narrower, the ring stands above the table. */
@container an-split (min-width: 54rem) {
    .an-split-grid {
        grid-template-columns: 188px minmax(0, 1fr);
        gap: 28px;
    }
}

.an-split-note {
    margin-top: var(--space-4);
    padding-top: var(--space-3);
    border-top: 1px solid var(--color-border);
    color: var(--color-text-subtle);
    font-size: var(--text-xs);
}

/* The colour of a thing, Ring::stepClass(): the same custom property fills
   a slice and a swatch. */
.an-step-1 { --an-step: var(--color-ring-1); }
.an-step-2 { --an-step: var(--color-ring-2); }
.an-step-3 { --an-step: var(--color-ring-3); }
.an-step-4 { --an-step: var(--color-ring-4); }
.an-step-5 { --an-step: var(--color-ring-5); }
.an-step-other { --an-step: var(--color-ring-other); }

.an-ring {
    position: relative;
    width: 176px;
    max-width: 100%;
    margin: 0 auto;
}

.an-ring svg {
    width: 100%;
    height: auto;
}

.an-ring-slice {
    fill: var(--an-step);
}

@media (hover: hover) {
    .an-ring svg:hover .an-ring-slice:not(:hover) {
        opacity: 0.5;
    }
}

.an-ring-centre {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
    pointer-events: none;
}

.an-ring-centre b {
    font-size: 22px;
    font-weight: var(--weight-semibold);
    letter-spacing: -0.02em;
    line-height: 1.1;
}

.an-ring-centre span {
    color: var(--color-text-subtle);
    font-size: var(--text-xs);
}

.an-name {
    display: inline-flex;
    align-items: center;
    gap: 10px;
}

.an-swatch {
    display: inline-block;
    flex: none;
    width: 10px;
    height: 10px;
    border-radius: 3px;
    background: var(--an-step);
}

/* The table beside the ring runs flush with the card's content and has no
   grey head, and it keeps its columns down to 24rem: four narrow columns
   fit where the admin's tables would already be cards. Below, its rows turn
   into cards as every table of the admin does (components.css). */
.an-table-wrap {
    overflow-x: auto;
    container-type: inline-size;
}

.an-table-wrap .table th {
    background: none;
}

.an-table-wrap .table td {
    padding-top: var(--space-3);
    padding-bottom: var(--space-3);
    font-variant-numeric: tabular-nums;
}

.an-table-wrap .table th:first-child,
.an-table-wrap .table td:first-child {
    padding-left: 0;
}

.an-table-wrap .table th:last-child,
.an-table-wrap .table td:last-child {
    padding-right: 0;
}

.an-table-wrap .table th .an-info {
    margin: -4px 0;
}

@container (max-width: 24rem) {
    .an-table-wrap .table thead {
        position: absolute;
        width: 1px;
        height: 1px;
        overflow: hidden;
        clip: rect(0, 0, 0, 0);
    }

    .an-table-wrap .table,
    .an-table-wrap .table tbody,
    .an-table-wrap .table tr {
        display: block;
        width: 100%;
    }

    .an-table-wrap .table tr {
        padding: var(--space-4) 0;
        border-top: 1px solid var(--color-border);
    }

    .an-table-wrap .table tbody tr:first-child {
        border-top: 0;
    }

    .an-table-wrap .table td,
    .an-table-wrap .table td:first-child,
    .an-table-wrap .table td:last-child {
        position: relative;
        display: block;
        padding: 3px 0;
        border: 0;
        overflow-wrap: anywhere;
        text-align: left;
    }

    .an-table-wrap .table td[data-label],
    .an-table-wrap .table td[data-label]:first-child,
    .an-table-wrap .table td[data-label]:last-child {
        padding-left: 8.5rem;
    }

    .an-table-wrap .table td[data-label]::before {
        content: attr(data-label);
        position: absolute;
        top: 3px;
        left: 0;
        width: 7.5rem;
        color: var(--color-text-subtle);
        font-size: var(--text-sm);
        font-weight: var(--weight-medium);
        line-height: 1.7;
    }

    .an-table-wrap .table td.cell-primary {
        padding-bottom: var(--space-2);
        font-size: var(--text-md);
    }
}

/* ------------------------------------------------------------------------
   The breakdown by country (WorldMap, D82, D83): the world's countries
   beside the countries with the most visits, under it where the card is
   narrow. A country with visits is filled in its blue, the rest grey, and
   every border is a hairline in the card's colour that keeps its width
   when the view changes. A small country's dot is a line without length
   whose round cap keeps its size in pixels too. The pointer on a country
   or its row lights both (analytics.js, .is-lit): the country outlined in
   ink, the rest of the countries with visits dimmed.
   ------------------------------------------------------------------------ */

.an-geo {
    container: an-geo / inline-size;
}

.an-geo-grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-5);
    align-items: center;
}

@container an-geo (min-width: 46rem) {
    .an-geo-grid {
        grid-template-columns: minmax(0, 1fr) minmax(15rem, 19rem);
        gap: 40px;
    }
}

.an-map-1 { --an-map: var(--color-map-1); }
.an-map-2 { --an-map: var(--color-map-2); }
.an-map-3 { --an-map: var(--color-map-3); }
.an-map-4 { --an-map: var(--color-map-4); }
.an-map-5 { --an-map: var(--color-map-5); }

.an-map {
    display: block;
    width: 100%;
    height: auto;
}

.an-map-land,
.an-map-place {
    stroke: var(--color-surface);
    stroke-width: 0.6px;
    stroke-linejoin: round;
    vector-effect: non-scaling-stroke;
}

.an-map-land {
    fill: var(--color-map-land);
    pointer-events: none;
}

.an-map-place {
    fill: var(--an-map);
}

.an-map-place.is-lit {
    stroke: var(--color-chart-ink);
    stroke-width: 1.5px;
}

.an-map-dot path {
    fill: none;
    stroke-linecap: round;
    vector-effect: non-scaling-stroke;
}

.an-map-dot .an-map-halo {
    stroke: var(--color-surface);
    stroke-width: 10px;
}

.an-map-dot .an-map-mark {
    stroke: var(--an-map);
    stroke-width: 7px;
}

.an-map-dot.is-lit .an-map-halo {
    stroke: var(--color-chart-ink);
}

.an-map.is-lit .an-map-place:not(.is-lit),
.an-map.is-lit .an-map-dot:not(.is-lit) {
    opacity: 0.35;
}

.an-geo-foot {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    margin-top: var(--space-3);
}

.an-geo-legend {
    display: flex;
    align-items: center;
    gap: 4px;
    color: var(--color-text-subtle);
    font-size: var(--text-xs);
}

.an-geo-legend span:first-child {
    margin-right: 4px;
}

.an-geo-legend span:last-child {
    margin-left: 4px;
}

.an-geo-swatch {
    display: inline-block;
    width: 14px;
    height: 8px;
    border-radius: 2px;
    background: var(--an-map);
}

/* World and Europe: a segmented control of buttons, which script shows. */
.an-geo-zoom .an-seg-item {
    min-height: 28px;
    padding: 0 10px;
    border: 0;
    background: none;
    font: inherit;
    font-size: var(--text-sm);
    font-weight: var(--weight-medium);
    cursor: pointer;
}

.an-geo-zoom .an-seg-item[aria-pressed="true"] {
    background: var(--color-surface-raised);
    color: var(--color-text);
    box-shadow: var(--shadow-sm);
}

/* A country's dot beside its name in the list; Other has none, and keeps
   its room. */
.an-geo-key {
    display: inline-block;
    flex: none;
    width: 8px;
    height: 8px;
    border-radius: var(--radius-full);
    background: var(--an-map);
}

.an-geo-key.is-none {
    background: none;
}

.an-geo-list {
    display: flex;
    flex-direction: column;
    gap: 4px;
    margin: 0;
    padding: 0;
    list-style: none;
}

/* A row on the bar of its share: the bar is an SVG behind the words, its
   width an attribute, as the page has no style attributes. */
.an-geo-row {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    min-height: 36px;
    padding: 0 10px;
    border-radius: 6px;
    font-variant-numeric: tabular-nums;
}

.an-geo-bar {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    overflow: visible;
    pointer-events: none;
}

.an-geo-bar rect {
    fill: var(--color-chart-wash);
}

.an-geo-row.is-lit {
    background: var(--color-chart-wash);
}

/* A row takes the focus for its tooltip; the ring sits inside it. */
.an-geo-row:focus-visible {
    outline-offset: -2px;
}

.an-geo-name,
.an-geo-value {
    position: relative;
}

.an-geo-name {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    min-width: 0;
    font-weight: var(--weight-medium);
}

.an-geo-name > span {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.an-geo-value {
    flex: none;
    font-weight: var(--weight-semibold);
}

.an-geo-share {
    margin-left: 4px;
    color: var(--color-text-subtle);
    font-weight: var(--weight-normal);
}

/* ------------------------------------------------------------------------
   The heatmap (Heatmap): 24 hours by 7 days, square cells 3 pixels apart
   at every width. The cells' SVG reaches 1.5 pixels past its column on
   every side, as each cell's stroke takes that much off its edges.
   ------------------------------------------------------------------------ */

.an-heat {
    display: grid;
    grid-template-columns: 30px minmax(0, 1fr);
    gap: 3px;
    max-width: 820px;
}

.an-heat-hours {
    position: relative;
    grid-column: 2;
    height: 15.5px;
    color: var(--color-text-subtle);
    font-size: 10px;
    line-height: 1.55;
}

.an-heat-hour {
    position: absolute;
    top: 0;
}

.an-heat-hour-0 { left: 0; }
.an-heat-hour-6 { left: 25%; }
.an-heat-hour-12 { left: 50%; }
.an-heat-hour-18 { left: 75%; }

.an-heat-days {
    display: grid;
    grid-column: 1;
    grid-template-rows: repeat(7, minmax(0, 1fr));
    margin: -1.5px 0;
    color: var(--color-text-subtle);
    font-size: 11px;
    line-height: 1;
}

.an-heat-days span {
    display: flex;
    align-items: center;
}

.an-heat-cells {
    display: block;
    grid-column: 2;
    width: calc(100% + 3px);
    max-width: none;
    height: auto;
    aspect-ratio: 24 / 7;
    margin: -1.5px;
    overflow: visible;
}

.an-level-0 { --an-level: var(--color-heat-0); }
.an-level-1 { --an-level: var(--color-heat-1); }
.an-level-2 { --an-level: var(--color-heat-2); }
.an-level-3 { --an-level: var(--color-heat-3); }
.an-level-4 { --an-level: var(--color-heat-4); }
.an-level-5 { --an-level: var(--color-heat-5); }

.an-heat-cell {
    fill: var(--an-level);
    stroke: var(--color-surface);
    stroke-width: 3;
}

/* The cell under the pointer, outlined by analytics.js. */
.an-heat-focus {
    fill: none;
    stroke: none;
    pointer-events: none;
}

.an-heat-focus.is-shown {
    stroke: var(--color-focus);
    stroke-width: 2;
}

.an-heat-legend {
    display: flex;
    align-items: center;
    gap: 6px;
    margin-top: var(--space-3);
    color: var(--color-text-subtle);
    font-size: var(--text-xs);
}

.an-heat-key {
    width: 14px;
    height: 14px;
    border-radius: 3px;
    background: var(--an-level);
}

/* ------------------------------------------------------------------------
   When posts do best (PostingTimes): the Heatmap's grid of 24 hours by 7
   days, its cells HTML rather than SVG, 3 pixels apart, in five of its
   greys from below to above the usual; an hour without a reel the
   lightest, one with fewer than 3 reels an outlined square. [Phase 5,
   sections 3.7 and 9.2]
   ------------------------------------------------------------------------ */

.an-posting-cells {
    display: grid;
    grid-column: 2;
    grid-template-columns: repeat(24, minmax(0, 1fr));
    gap: 3px;
}

.an-posting-cell {
    aspect-ratio: 1 / 1;
    border-radius: 3px;
    background: var(--an-level, var(--color-heat-0));
}

.an-posting-few {
    border: 1px dashed var(--color-control-border);
    background: transparent;
}

@media (hover: hover) {
    .an-posting-cell[data-an-tip]:hover {
        outline: 2px solid var(--color-focus);
        outline-offset: 1px;
    }
}

/* The grid before 30 reels are compared [D77]: every cell in the ghost
   grey, a soft pattern a little darker, the cells fading out to the right
   while the hours and days stay. */
/* The cells and the chip on them, in the cells' column. */
.an-posting-ghost {
    grid-column: 2;
}

.an-posting.is-ghost .an-posting-cells {
    -webkit-mask-image: linear-gradient(to right, black 0, black 55%, transparent 100%);
    mask-image: linear-gradient(to right, black 0, black 55%, transparent 100%);
}

.an-posting.is-ghost .an-posting-cell {
    background: var(--color-ghost);
}

.an-posting.is-ghost .an-posting-cell.is-strong {
    background: var(--color-ghost-strong);
}

.an-posting-legend {
    flex-wrap: wrap;
    gap: 6px var(--space-4);
}

.an-posting-scale {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

/* ------------------------------------------------------------------------
   The Accounts tab (D83): a model's row as on Home, its face, its name and
   how many accounts, its totals in semibold; under it its accounts,
   indented to its name, with no line between them, so a model and its
   accounts read as one block. An account's handle opens its numbers.
   ------------------------------------------------------------------------ */

.an-row-link {
    text-decoration: none;
}

@media (hover: hover) {
    .an-row:hover .an-row-link {
        text-decoration: underline;
    }
}

.an-group td.cell-num {
    font-weight: var(--weight-semibold);
}

.an-row td {
    height: 48px;
    border-top: 0;
}

.an-row td.cell-num {
    font-weight: var(--weight-normal);
}

/* An account without a link in the period stands on the muted surface, its
   whole row and the cell that stays in place with it, its words and figures
   as they are, so the accounts still missing a link stand out at a glance
   (D115; the developer's ask: the row, not its writing). Under the pointer
   it stays as it is. */
.table tbody .an-row.is-unlinked td,
.table tbody .an-row.is-unlinked:hover td {
    background: var(--color-surface-muted);
}

/* An account starts where its model's name does: the picture's 32 pixels
   and the gap after it further in. */
.table .an-row td:first-child {
    padding-left: calc(var(--space-5) + 44px);
}

@media (min-width: 640px) {
    .table .an-row td:first-child {
        padding-left: calc(var(--space-6) + 44px);
    }
}

/* The last account of a model keeps some air before the next model. */
.an-row:last-child td,
.an-row:has(+ .an-group) td {
    padding-bottom: 14px;
}

.an-account {
    display: flex;
    align-items: center;
    gap: 10px;
    min-width: 0;
}

/* The platform's mark in its rounded square, in its brand's colours where
   it has them (platform-<key>, components.css), grey otherwise. */
.an-account-icon {
    display: grid;
    flex: none;
    place-items: center;
    width: 30px;
    height: 30px;
    border: 1px solid var(--mark-border, var(--color-border));
    border-radius: var(--radius-sm);
    background: var(--mark-bg, var(--color-surface-muted));
    color: var(--mark-fg, var(--color-text-muted));
}

.an-account-icon svg {
    width: 16px;
    height: 16px;
}

/* The platforms' marks (Glyphs) are filled, the admin's icons stroked. */
.an-account-icon .glyph {
    fill: currentColor;
}

/* A head that sorts (partials/sort-head.php, D101): its label, under it
   a quiet second line where the head says more ("3 days"), and its mark,
   Lucide's chevrons-up-down at 45% while its column does not sort, full
   under the pointer, and the arrow of its order while it does, the head
   then in the text's colour. */
.an-sort {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    color: inherit;
    text-decoration: none;
}

.an-sort.is-sorted {
    color: var(--color-text);
}

.an-sort-text {
    display: inline-flex;
    flex-direction: column;
    line-height: 1.25;
}

th.cell-num .an-sort-text {
    align-items: flex-end;
}

.an-sort-sub {
    color: var(--color-text-subtle);
    font-weight: var(--weight-normal);
}

.an-sort .icon {
    flex: none;
    width: 12px;
    height: 12px;
}

.an-sort-idle {
    opacity: 0.45;
}

@media (hover: hover) {
    .an-sort:hover {
        color: var(--color-text);
    }

    .an-sort:hover .an-sort-idle {
        opacity: 1;
    }
}

/* ------------------------------------------------------------------------
   The tooltip analytics.js adds to <body>, or to the record panel that
   holds what it describes (D76): over the chart, the ring, the heatmap, a
   marker and the browser's band
   ------------------------------------------------------------------------ */

.an-tip {
    position: fixed;
    z-index: var(--z-dialog);
    min-width: 150px;
    max-width: 260px;
    padding: var(--space-2) 10px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    background: var(--color-surface);
    box-shadow: var(--shadow-lg);
    font-size: var(--text-xs);
    pointer-events: none;
}

.an-tip-title {
    color: var(--color-text-subtle);
    font-weight: var(--weight-medium);
}

.an-tip-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 14px;
    margin-top: 3px;
}

.an-tip-row b {
    font-size: var(--text-base);
    font-weight: var(--weight-semibold);
    font-variant-numeric: tabular-nums;
}

.an-tip-row span {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    color: var(--color-text-muted);
}

/* The keys of a tooltip over time: the current period in the ink, in the
   blue where the chart draws it blue (data-an-key, D101), the period
   before grey. */
.an-tip-key {
    display: inline-block;
    width: 12px;
    height: 2px;
    border-radius: 1px;
    background: var(--color-chart-ink);
}

.an-tip-key-current {
    background: var(--color-chart-line);
}

.an-tip-key-prev {
    background: var(--color-chart-prev);
}

/* A lane's figure under the chart, in the chart's blue (D106). */
.an-tip-key-lane {
    background: var(--color-chart-line);
}

.an-tip-key-square {
    width: 10px;
    height: 10px;
    border-radius: 3px;
    background: var(--an-step);
}

.an-tip-strong {
    margin-top: 3px;
    font-size: var(--text-sm);
    font-weight: var(--weight-semibold);
}

.an-tip-strong:first-child {
    margin-top: 0;
}

.an-tip-note {
    margin-top: 2px;
    color: var(--color-text-subtle);
}

/* The followers of a bucket not shared out to reels, after the small
   amber triangle (D103). */
.an-tip-warn {
    display: flex;
    align-items: center;
    gap: 5px;
    margin-top: 3px;
    color: var(--color-text-muted);
}

.an-tip-warn .icon {
    flex: none;
    width: 12px;
    height: 12px;
    color: var(--color-warning-text);
}

/* ------------------------------------------------------------------------
   Ghosts of the cards (D91): what the funnel, the breakdown and the
   heatmap show without a visit in their period, in the ghost greys of
   components.css, with the funnel's title and line or a card's chip
   centred on it (Ghost::funnel(), map(), ring(), heat(), rows()).
   ------------------------------------------------------------------------ */

/* The funnel's words above its band rather than over it: the band is
   solid, where a chart's ghost is a line. */
.ghost-funnel {
    display: block;
    width: 100%;
    height: 88px;
    margin-top: var(--space-6);
}

@media (min-width: 640px) {
    .ghost-funnel {
        height: 132px;
    }
}

.ghost-shape {
    fill: var(--color-ghost);
}

.ghost-shape-strong {
    fill: var(--color-ghost-strong);
}

.ghost-map-land {
    fill: var(--color-ghost-strong);
    stroke: var(--color-surface);
    stroke-width: 0.6px;
    stroke-linejoin: round;
    vector-effect: non-scaling-stroke;
}

.ghost-ring {
    fill: none;
    stroke: var(--color-ghost-strong);
    stroke-width: 24;
}

.ghost-rows {
    display: flex;
    flex-direction: column;
    gap: 4px;
    margin: 0;
    padding: 0;
    list-style: none;
}

.ghost-rows > li {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    min-height: 36px;
    padding: 0 10px;
}

.ghost-rows > li > .ghost-bar {
    width: 44%;
}

.ghost-rows > li > .ghost-bar-sm {
    width: 12%;
}

.ghost-rows > li:nth-child(3n + 2) > .ghost-bar {
    width: 34%;
}

.ghost-rows > li:nth-child(3n) > .ghost-bar {
    width: 52%;
}

/* The grid alone, without the days and hours, centred in its card so
   that the chip stands on its middle. */
.ghost-heat-wrap .an-heat {
    grid-template-columns: minmax(0, 1fr);
    margin-inline: auto;
}

.ghost-heat-wrap .an-heat-cells {
    grid-column: 1;
}

.ghost-heat-cell {
    stroke: var(--color-surface);
    stroke-width: 3;
}

.ghost-heat-0 { fill: var(--color-ghost); }
.ghost-heat-1 { fill: var(--color-ghost-strong); }
.ghost-heat-2 { fill: var(--color-ghost-line); }

/* ------------------------------------------------------------------------
   The live card (D116): the Funnel tab's last 30 minutes at its foot
   (partials/analytics/live-card.php, LiveChart), which analytics.js
   refreshes every 15 seconds while the page is in view. Its head with a
   green "Live", grey "Paused" while an answer fails; then, from a card of
   860 pixels, two columns: the two figures in a post's manner
   (.post-figures, posts.css) over the lines of the minutes, LineChart's
   drawing with the clicks in the ink; and the latest visits, a small box
   each, one under the other, as tall as the left column. On a phone the
   visits come under the lines and the figures take their short names.
   A new visit comes in at the top, rises out of the chart's wash and
   settles, the boxes under it move down, and the oldest fades away at the
   bottom; with reduced motion they simply change.
   ------------------------------------------------------------------------ */

.an-live {
    container: an-live / inline-size;
}

/* The title and its line on the left, Live on the right, on a phone too. */
.an-live-head {
    flex-wrap: nowrap;
}

.an-live-head > :first-child {
    flex: 1 1 auto;
    min-width: 0;
}

/* Whether the card refreshes itself: green while it does. */
.an-live-status {
    display: inline-flex;
    flex: none;
    align-items: center;
    gap: 6px;
    padding: 2px 10px 2px 8px;
    border: 1px solid var(--color-success-border);
    border-radius: var(--radius-full);
    background: var(--color-success-bg);
    color: var(--color-success-text);
    font-size: var(--text-xs);
    font-weight: var(--weight-semibold);
    line-height: 20px;
}

.an-live-status.is-paused {
    border-color: var(--color-border);
    background: var(--color-surface-muted);
    color: var(--color-text-muted);
}

.an-live-status.is-paused .live-dot {
    background: var(--color-text-subtle);
}

.an-live-body {
    display: grid;
    gap: var(--space-8);
}

.an-live-main,
.an-live-side {
    min-width: 0;
}

/* The figures side by side, each with the key of its line before its name. */
.an-live-figures {
    display: grid;
    grid-template-columns: repeat(2, max-content);
}

.an-live .post-figure-label .an-live-key {
    margin-right: 6px;
}

.an-live-short {
    display: none;
}

/* The times under the lines: the four LiveChart writes, always. */
.an-live-chart .an-x-label {
    display: inline;
}

.an-live-side-title {
    margin: 0 0 var(--space-3);
    color: var(--color-text-muted);
    font-size: var(--text-sm);
    font-weight: var(--weight-medium);
}

.an-live-feed {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    margin: 0;
    padding: 0;
    list-style: none;
}

/* A visit: a small box of its own, the platform's mark, who and from
   where, and how long ago with "Clicked" in the ink under it. */
.an-live-item {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    min-width: 0;
    min-height: 60px;
    padding: 10px 12px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    background: var(--color-surface-hover);
}

.an-live-item .an-account-icon {
    width: 32px;
    height: 32px;
}

.an-live-item-text {
    display: flex;
    flex: 1 1 auto;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}

.an-live-item-name,
.an-live-item-where {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.an-live-item-name {
    color: var(--color-text);
    font-weight: var(--weight-medium);
    text-decoration: none;
}

@media (hover: hover) {
    .an-live-item-name:hover {
        text-decoration: underline;
    }
}

.an-live-item-where {
    color: var(--color-text-muted);
    font-size: var(--text-xs);
}

.an-live-item-side {
    display: flex;
    flex: none;
    flex-direction: column;
    align-items: flex-end;
    gap: 4px;
}

.an-live-item-time {
    color: var(--color-text-subtle);
    font-size: var(--text-xs);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.an-live-item-clicked {
    padding: 0 8px;
    border-radius: var(--radius-full);
    background: var(--color-text);
    color: var(--color-surface);
    font-size: 11px;
    font-weight: var(--weight-semibold);
    line-height: 18px;
    white-space: nowrap;
}

/* Without a visit: the boxes in the ghost greys under the chip (D91). */
.an-live-item.is-ghost {
    border-color: var(--color-ghost);
    background: none;
}

.an-live-item.is-ghost .ghost-dot {
    width: 32px;
    height: 32px;
    border-radius: var(--radius-sm);
}

/* Two columns from a card of 860 pixels, the visits as tall as the figures
   and the lines beside them. */
@container an-live (min-width: 860px) {
    .an-live-body {
        grid-template-columns: minmax(0, 1fr) minmax(300px, 360px);
        gap: var(--space-10);
    }
}

/* A phone's card: the figures' short names, so both stay side by side. */
@container an-live (max-width: 559.98px) {
    .an-live-figures {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .an-live .post-figure {
        padding: 0 var(--space-4);
    }

    .an-live .post-figure:first-child {
        padding-left: 0;
    }

    .an-live-long {
        display: none;
    }

    .an-live-short {
        display: inline;
    }
}

/* A new visit comes in at the top out of the chart's wash, the others move
   down to make room (analytics.js sets where each was, then lets it go),
   and the oldest fades away where it stood. */
@keyframes an-live-in {
    from {
        opacity: 0;
        transform: translateY(-12px) scale(0.98);
    }
}

@keyframes an-live-wash {
    from {
        border-color: var(--color-chart-line);
        background-color: var(--color-chart-line-wash);
    }
}

@keyframes an-live-out {
    to {
        opacity: 0;
        transform: translateY(10px) scale(0.98);
    }
}

.an-live-item.is-new {
    animation: an-live-in 480ms cubic-bezier(0.2, 0.8, 0.2, 1) both, an-live-wash 2400ms ease-out both;
}

.an-live-item.is-moving {
    transition: transform 480ms cubic-bezier(0.2, 0.8, 0.2, 1);
}

.an-live-item.is-leaving {
    position: absolute;
    right: 0;
    left: 0;
    animation: an-live-out 360ms ease-in both;
    pointer-events: none;
}

@media (prefers-reduced-motion: reduce) {
    .an-live-item.is-new,
    .an-live-item.is-leaving {
        animation: none;
    }

    .an-live-item.is-moving {
        transition: none;
    }
}
