You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
svelte-kit-vice/src/uix/eidos/components/chart/chart.css

404 lines
14 KiB

/**
* Chart recipe — styling for the SVG frame, axes, grid, marks and the hover
* tooltip, plus the HTML chrome (title + legend) the presets compose. Every
* geometric constant (stroke widths, radii, opacities, transition timing,
* tooltip surface) comes from a `--chart-*` recipe token sourced from canonical
* primitives — see `lib/recipes/base.ts`. Series fills/strokes are themed per
* series inline (`var(--color-{role}-solid)`).
*
* TEXT takes its SIZE ROLE from the canon's named styles — `caption` for the
* annotations (axis labels, legend, tooltip, smith labels) and `label` for the
* chrome text (title, bar-list rows, funnel) — and its INK and WEIGHT from the
* system's content / weight slots, which is what those slots are for. The
* recipe mints NO typography of its own (theming §6, D-TH.2 precedent:
* code-block / kbd / announce read the same layer).
*
* What the recipe DOES own, because nothing else can name it: the ink of the
* lines and fills that are not text — axis, grid, the hairline that separates
* adjacent marks, the rails — plus its geometry.
*/
[data-chart-frame] {
display: flex;
flex-direction: column;
gap: var(--chart-gap);
inline-size: 100%;
}
[data-chart-plot] {
position: relative; /* anchor for the absolutely-positioned hover tooltip */
inline-size: 100%;
}
/* The plotting surface (morfo Provider — role="img"). */
[data-chart] {
display: block;
inline-size: 100%;
block-size: auto;
overflow: visible;
font-family: inherit;
}
/* Localised empty state when there is no data. */
[data-chart-empty] {
display: grid;
place-items: center;
block-size: 100%;
color: var(--color-content-secondary);
font-size: var(--style-label-font-size);
}
/* ── Axes ─────────────────────────────────────────────────────────────── */
[data-chart-axis-line],
[data-chart-axis-tick] {
stroke: var(--chart-axis-fg);
stroke-width: var(--chart-axis-width);
}
[data-chart-axis-label] {
fill: var(--color-content-secondary);
font-size: var(--style-caption-font-size);
}
/* ── Grid ─────────────────────────────────────────────────────────────── */
[data-chart-grid-line] {
stroke: var(--chart-grid-fg);
stroke-width: var(--chart-grid-width);
}
/* ── Marks ────────────────────────────────────────────────────────────── */
[data-chart-line] {
stroke-width: var(--chart-line-width);
transition: opacity var(--chart-transition-duration) var(--chart-transition-ease);
}
[data-chart-area] {
fill-opacity: var(--chart-area-opacity);
/* So the `grow` enter scales the area from its own bottom edge (the baseline) — it fills up. */
transform-box: fill-box;
transition: opacity var(--chart-transition-duration) var(--chart-transition-ease);
}
[data-chart-bar] {
rx: var(--chart-bar-radius);
/* So the `grow` enter's transform-origin (50% 100%) is the bar's own box, not the SVG viewport. */
transform-box: fill-box;
transition: opacity var(--chart-transition-duration) var(--chart-transition-ease);
}
[data-chart-point] {
r: var(--chart-point-radius);
transition: opacity var(--chart-transition-duration) var(--chart-transition-ease);
}
/* Pie / donut slices, separated by a hairline of the page surface. */
[data-chart-slice] {
stroke: var(--chart-separator-fg);
stroke-width: var(--chart-slice-stroke-width);
/* So the `bloom` enter scales each slice from the chart (viewport) centre — a radial grow. */
transform-box: view-box;
transition: opacity var(--chart-transition-duration) var(--chart-transition-ease);
}
/* ── Hover crosshair + active markers ─────────────────────────────────── */
[data-chart-crosshair] {
stroke: var(--chart-crosshair-fg);
stroke-width: var(--chart-crosshair-width);
stroke-dasharray: 3 3;
pointer-events: none;
}
[data-chart-active-dot] {
r: var(--chart-point-radius);
stroke: var(--chart-separator-fg);
stroke-width: var(--chart-axis-width);
pointer-events: none;
}
/* ── Hover tooltip ────────────────────────────────────────────────────── */
[data-chart-tooltip] {
position: absolute;
z-index: var(--z-index-tooltip);
pointer-events: none;
/* Anchored at the active datum's x (inline `left`) + cursor y (`top`);
offset to the side and vertically centred. Flips left near the edge. */
transform: translate(var(--space-3), -50%);
/* Glide between data points + flip side smoothly (the abrupt jump otherwise). */
transition:
left var(--chart-transition-duration) var(--chart-transition-ease),
transform var(--chart-transition-duration) var(--chart-transition-ease);
display: flex;
flex-direction: column;
gap: var(--chart-tooltip-gap);
padding: var(--chart-tooltip-padding);
background: var(--chart-tooltip-bg);
border: var(--chart-axis-width) solid var(--chart-tooltip-border);
border-radius: var(--chart-tooltip-radius);
box-shadow: var(--chart-tooltip-shadow);
font-size: var(--style-caption-font-size);
color: var(--color-content-primary);
min-inline-size: max-content;
}
[data-chart-tooltip][data-flip='true'] {
transform: translate(calc(-100% - var(--space-3)), -50%);
}
[data-chart-tooltip-x] {
font-weight: var(--font-weight-medium);
color: var(--color-content-primary);
}
[data-chart-tooltip-row] {
display: flex;
align-items: center;
gap: var(--chart-tooltip-gap);
color: var(--color-content-secondary);
}
[data-chart-tooltip-swatch] {
inline-size: var(--chart-tooltip-swatch-size);
block-size: var(--chart-tooltip-swatch-size);
border-radius: var(--chart-swatch-radius);
flex: none;
}
[data-chart-tooltip-value] {
margin-inline-start: var(--space-4);
font-variant-numeric: tabular-nums;
color: var(--color-content-primary);
}
/* ── Figure chrome (presets) ──────────────────────────────────────────── */
[data-chart-figure] {
/* Reset the browser's default <figure> margin (1em 40px) so the chart fills
and aligns with its container instead of sitting inset / off-centre. */
margin: 0;
position: relative; /* anchor for the pie's hover tooltip */
display: flex;
flex-direction: column;
gap: var(--chart-gap);
inline-size: 100%;
}
[data-chart-title] {
margin: 0;
font-size: var(--style-label-font-size);
font-weight: var(--font-weight-medium);
color: var(--color-content-primary);
}
[data-chart-legend] {
display: flex;
flex-wrap: wrap;
row-gap: var(--chart-legend-row-gap);
column-gap: var(--chart-legend-column-gap);
align-items: center;
}
[data-chart-legend-item] {
display: inline-flex;
align-items: center;
gap: var(--chart-legend-item-gap);
font-size: var(--style-caption-font-size);
color: var(--color-content-secondary);
}
[data-chart-swatch] {
inline-size: var(--chart-swatch-size);
block-size: var(--chart-swatch-size);
border-radius: var(--chart-swatch-radius);
flex: none;
}
/* ── Bar list (ranked horizontal bars) ────────────────────────────────── */
/* ONE grid for the whole list so the label / track / value columns line up
across every row — the track (the grey "100%" rail) is then identical-width
on every row, so the filled bars are directly comparable. */
[data-chart-bar-list] {
position: relative; /* anchor for the hover tooltip */
display: grid;
grid-template-columns: minmax(0, max-content) 1fr auto;
align-items: center;
row-gap: var(--chart-bar-list-row-gap);
column-gap: var(--chart-bar-list-column-gap);
inline-size: 100%;
}
[data-chart-bar-list-item] {
display: grid;
grid-column: 1 / -1;
grid-template-columns: subgrid;
align-items: center;
}
[data-chart-bar-list-label] {
font-size: var(--style-label-font-size);
color: var(--color-content-primary);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
[data-chart-bar-list-track] {
block-size: var(--chart-track-height);
background: var(--chart-track-bg);
border-radius: var(--chart-track-radius);
overflow: hidden;
}
[data-chart-bar-list-bar] {
block-size: 100%;
border-radius: var(--chart-bar-radius);
transition: inline-size var(--chart-transition-duration) var(--chart-transition-ease);
}
[data-chart-bar-list-value] {
font-size: var(--style-label-font-size);
color: var(--color-content-secondary);
font-variant-numeric: tabular-nums;
text-align: end;
}
/* ── Bar segment (single stacked bar) ─────────────────────────────────── */
[data-chart-bar-segment] {
position: relative; /* anchor for the hover tooltip */
display: flex;
flex-direction: column;
gap: var(--chart-bar-segment-gap);
inline-size: 100%;
}
[data-chart-bar-segment-track] {
display: flex;
gap: var(--chart-bar-segment-track-gap);
block-size: var(--chart-track-height);
border-radius: var(--chart-bar-segment-track-radius);
overflow: hidden;
}
[data-chart-bar-segment-fill] {
block-size: 100%;
min-inline-size: var(--chart-bar-segment-fill-min-inline-size);
transition:
inline-size var(--chart-transition-duration) var(--chart-transition-ease),
opacity var(--chart-transition-duration) var(--chart-transition-ease);
}
[data-chart-bar-segment-fill][data-dim='true'] {
opacity: var(--opacity-scrim);
}
[data-chart-bar-segment-legend] {
display: flex;
flex-wrap: wrap;
row-gap: var(--chart-bar-segment-legend-row-gap);
column-gap: var(--chart-bar-segment-legend-column-gap);
}
[data-chart-bar-segment-legend-item] {
display: inline-flex;
align-items: center;
gap: var(--chart-legend-item-gap);
font-size: var(--style-caption-font-size);
color: var(--color-content-secondary);
}
[data-chart-bar-segment-legend-value] {
color: var(--color-content-primary);
font-variant-numeric: tabular-nums;
}
/* ── Radar / spider chart ─────────────────────────────────────────────── */
[data-chart-radar-ring],
[data-chart-radar-spoke] {
fill: none;
stroke: var(--chart-grid-fg);
stroke-width: var(--chart-grid-width);
}
[data-chart-radar-area] {
fill-opacity: var(--chart-area-opacity);
stroke-width: var(--chart-line-width);
stroke-linejoin: round;
/* So the `bloom` enter scales the polygon from the radar centre — each vertex
travels from the origin to its place. */
transform-box: view-box;
}
/* ── Heatmap (grid of value-coloured cells) ───────────────────────────────── */
[data-chart-heat-cell] {
rx: var(--chart-bar-radius);
transition: opacity var(--chart-transition-duration) var(--chart-transition-ease);
}
[data-chart-heat-cell][data-dim='true'] {
opacity: var(--opacity-scrim);
}
/* Calendar heatmap (GitHub-style day cells). */
[data-chart-cal-cell] {
rx: var(--chart-bar-radius);
transition: opacity var(--chart-transition-duration) var(--chart-transition-ease);
}
[data-chart-cal-cell][data-dim='true'] {
opacity: var(--opacity-scrim);
}
/* Smith chart (RF reflection-coefficient disk). */
[data-chart-smith-boundary] {
fill: none;
stroke: var(--chart-smith-boundary-fg);
stroke-width: var(--border-width-medium);
}
[data-chart-smith-grid] {
fill: none;
stroke: var(--chart-axis-fg);
stroke-width: var(--border-width-thin);
}
[data-chart-smith-label] {
fill: var(--color-content-secondary);
font-size: var(--style-caption-font-size);
font-variant-numeric: tabular-nums;
pointer-events: none;
}
[data-chart-smith-point] {
stroke: var(--chart-separator-fg);
stroke-width: var(--border-width-medium);
}
[data-chart-smith-point-label] {
fill: var(--color-content-primary);
font-size: var(--style-caption-font-size);
font-weight: var(--font-weight-medium);
pointer-events: none;
}
/* ── Polar area (Nightingale / coxcomb petals) ────────────────────────────── */
[data-chart-polar-petal] {
stroke: var(--chart-separator-fg);
stroke-width: var(--chart-slice-stroke-width);
fill-opacity: 0.9;
/* So the `bloom` enter scales each petal from the chart centre (radial grow). */
transform-box: view-box;
transition: opacity var(--chart-transition-duration) var(--chart-transition-ease);
}
[data-chart-polar-petal][data-dim='true'] {
opacity: var(--opacity-scrim);
}
/* ── Funnel (tapering stages) ─────────────────────────────────────────────── */
[data-chart-funnel-segment] {
stroke: var(--chart-separator-fg);
stroke-width: var(--chart-slice-stroke-width);
}
[data-chart-funnel-label] {
font-size: var(--style-label-font-size);
font-weight: var(--font-weight-medium);
pointer-events: none;
}
/* Right-side labels (always legible — theme text colour, never on a coloured fill). */
[data-chart-funnel-connector] {
stroke: var(--chart-axis-fg);
stroke-width: var(--chart-grid-width);
}
[data-chart-funnel-side] {
font-size: var(--style-label-font-size);
}
[data-chart-funnel-name] {
fill: var(--color-content-primary);
font-weight: var(--font-weight-medium);
}
[data-chart-funnel-meta] {
fill: var(--color-content-secondary);
font-variant-numeric: tabular-nums;
}
/* ── Gauge (radial single value) ──────────────────────────────────────────── */
[data-chart-gauge-track] {
fill: var(--chart-track-bg);
}
[data-chart-gauge-value] {
transition: opacity var(--chart-transition-duration) var(--chart-transition-ease);
}
[data-chart-gauge-label] {
fill: var(--color-content-primary);
font-size: var(--font-size-xl);
font-weight: var(--font-weight-medium);
font-variant-numeric: tabular-nums;
}

Powered by TurnKey Linux.