/*
 * A CSS icon: a gradient tile with up to three characters or one Material Symbol, and
 * an optional corner badge. No image anywhere — everything here is drawn from the
 * custom properties Mf_Css_Icon_Render puts on the wrapper, so ONE size value drives
 * the font, the padding, the badge and its offsets.
 *
 * Two authorable MULTIPLIERS ride on top of that chain (SPEC-icon-surface.md §7.11):
 * `--mf-ci-content-scale` and `--mf-ci-badge-scale`, both defaulting to `1`. They
 * multiply the ratios below rather than replacing them, which is the whole design of
 * the thing: the em-chain keeps its shape, so the three repairs keep holding, and a
 * scale of `1` is byte-identical to the icon before the scales existed. Anything that
 * needs a new absolute length here is almost certainly the wrong idea — multiply.
 *
 * Markup contract (Mf_Css_Icon_Render is the only thing allowed to produce it):
 *
 *     <span class="mf-ci [mf-ci--inline] [mf-ci--has-badge]" style="--mf-ci-size:…">
 *         <span class="mf-ci__tile mf-ci__tile--rounded">
 *             <span class="mf-ci__text">mAI</span>
 *         </span>
 *         <span class="mf-ci__badge mf-ci__badge--top-right">
 *             <span class="mf-ci__badge-text">new</span>
 *         </span>
 *     </span>
 *
 * Three of the rules below are not style but repairs, and all three were found the
 * hard way in `marketing/mf-icon-designer`, this feature's design reference. They are
 * carried over with their reasons because each one looks removable and is not.
 */

/*
 * The wrapper is the bounding box, and it is what the badge anchors to.
 *
 * REPAIR 1 — the padding. Without it the badge projects past the wrapper's edge, and
 * any ancestor with `overflow: hidden` clips it. The padding makes the wrapper
 * genuinely contain its own contents.
 *
 * `vertical-align: middle` centres the wrapper against the surrounding text's
 * x-height. For an icon near text size that lands optically on the line; for a
 * larger one the line box grows and the text centres against the icon, which is the
 * symmetric result rather than text clinging to the icon's bottom edge.
 */
.mf-ci {
	position: relative;
	display: inline-flex;
	vertical-align: middle;
}

/*
 * The padding IS the badge's projection, and that is worth stating because it is not
 * obvious from the two rules that produce it. The badge is absolutely positioned at
 * `top/right: 0`, and an absolute offset is measured from the containing block's
 * PADDING box — i.e. from the wrapper's outer edge. So the badge's outer edge lands
 * exactly on that edge whatever this value is, and what the value decides is how far
 * the tile sits away from it: the padding is how much of the badge hangs off the tile,
 * and the rest of the badge lies ON the tile.
 *
 * `0.09` rather than the `0.18` this shipped with, which is the iOS notification-dot
 * placement the author asked for (divb-hq#43). At 0.18 an EMPTY badge — 0.28em, the
 * smallest thing here — hung two thirds outside the tile, and since the tile's corner
 * is rounded away at 0.18em radius the dot appeared to float diagonally off the corner
 * rather than to sit on it. At 0.09 the dot covers the corner arc and roughly a third
 * of it still overhangs, which reads as a notification dot.
 *
 * Scaled with the badge, so a discreet badge does not leave the wrapper padded for a
 * full-size one — the padding and the projection cannot disagree, because they are the
 * same declaration.
 */
.mf-ci--has-badge {
	padding: calc(var(--mf-ci-size, 2rem) * 0.09 * var(--mf-ci-badge-scale, 1));
}

/*
 * REPAIR 2 — `font-size` first, on the tile itself.
 *
 * The tile's width and height are declared in `1em`, and they must resolve against
 * `--mf-ci-size` rather than against whatever font-size the surrounding text has. So
 * the tile establishes its own font-size context first. Without this split, a
 * placement of `--mf-ci-size: 1em` collapsed the tile to a handful of pixels: the
 * text's `font-size` and the box's `width: 1em` chained off one another.
 */
.mf-ci__tile {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 1em;
	height: 1em;

	/* The colour is the fallback for the gradient, so markup that somehow arrives
	   without the three properties still renders a filled tile rather than a
	   transparent hole. The renderer always writes all three. */
	background-color: var(--mf-ci-from, #e35205);
	background-image: linear-gradient(var(--mf-ci-angle), var(--mf-ci-from), var(--mf-ci-to));
	color: var(--mf-ci-ink, #fff);
	font-family: ui-monospace, "SF Mono", "Cascadia Mono", "Roboto Mono", monospace;
	font-size: var(--mf-ci-size, 2rem);
	font-weight: 700;
	line-height: 1;
	text-shadow: 0 1px 1px rgb(0 0 0 / 35%);
	text-transform: uppercase;
}

/* A system monospace stack, deliberately: the suite self-hosts every font it uses
   and names no webfont it does not ship. */

.mf-ci__tile--rounded {
	border-radius: 0.18em;
}

.mf-ci__tile--circle {
	border-radius: 50%;
}

/* Up to three characters, scaled down inside the tile so they sit in it rather than
   fill it. The ratio is the default and the author's scale multiplies it — three
   characters at 1.5 overflow the tile visibly, which is a choice made in front of a
   live preview rather than something to clamp away here. */
.mf-ci__text {
	font-size: calc(0.52em * var(--mf-ci-content-scale, 1));
	letter-spacing: 0.02em;
}

/*
 * The other content source: one Material Symbol instead of characters
 * (docs/SPEC-icon-surface.md §7.10). The glyph itself comes from Mf_Symbol, so this
 * rule only says how big it is inside the tile.
 *
 * SMALLER than the text's 0.52em, which looks wrong written down and is right on
 * screen: three characters at 0.52em stand about 0.36em tall (cap height), while a
 * glyph fills its em box almost completely. Matching the numbers would make every
 * symbol tile look heavier than every text tile beside it. Measured against a text
 * tile at the same --mf-ci-size.
 *
 * Which is exactly why the author's control is a MULTIPLIER and not a font size: the
 * same scale rides on both ratios, so "bigger content" keeps that measured difference
 * instead of flattening it. `--mf-ci-content-scale`, not `--mf-ci-text-scale`, for the
 * same reason — since §7.10 the tile's content may be a glyph, and one knob answers
 * "how big is what is in the tile" for both sources.
 */
.mf-ci__symbol {
	display: flex;
	align-items: center;
	justify-content: center;
	font-size: calc(0.4em * var(--mf-ci-content-scale, 1));
	line-height: 1;
}

/*
 * Turning the content — characters or glyph, whichever the tile carries
 * (`--mf-ci-content-rotate`, SPEC-icon-surface.md §7.12).
 *
 * On the CONTENT spans and never on the tile, which is the whole placement decision: the
 * tile carries the gradient, the shape and the badge's anchoring, so turning it would
 * turn all three. `--mf-ci-angle` above is the GRADIENT's angle and is a different
 * property on purpose — two angles live on one icon.
 *
 * Three things checked rather than assumed, because `transform` on an em-sized inline box
 * is where this file's surprises come from:
 *
 * 1. **No `display` change is needed.** `transform` is ignored on a purely inline box,
 *    but both spans are flex items of the tile and a flex item is blockified, so the
 *    transform applies as it stands. Adding `inline-block` here would be a fix for a
 *    problem this markup does not have.
 * 2. **The layout box does not move.** Measured at 5rem: an identity rotation leaves the
 *    text span at the same size and position to three decimals, so the tile's centring,
 *    the propagated baseline and REPAIR 1-3 are all untouched. That is why the rule can
 *    be unconditional instead of hiding behind a state class.
 * 3. **`transform-origin` stays the default centre**, which is the content's own middle —
 *    the flex centring places the box and the rotation turns it in place.
 */
.mf-ci__text,
.mf-ci__symbol {
	transform: rotate(var(--mf-ci-content-rotate, 0deg));
}

/*
 * The badge, anchored to the WRAPPER's corner rather than the tile's — which is what
 * makes REPAIR 1's padding the thing that keeps it visible, and what makes that same
 * padding decide how far the badge overlaps the tile.
 *
 * Every measurement here is multiplied by `--mf-ci-badge-scale`, box and text alike.
 * Scaling only the text would have shrunk the number inside an unchanged pill, which is
 * not what "das Badge trägt sehr auf" was about (divb-hq#43): the complaint is the
 * badge's footprint on a large tile, so the footprint is what scales.
 */
.mf-ci__badge {
	position: absolute;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: calc(0.42em * var(--mf-ci-badge-scale, 1));
	height: calc(0.42em * var(--mf-ci-badge-scale, 1));
	padding: 0 calc(0.1em * var(--mf-ci-badge-scale, 1));
	border-radius: 999px;
	background: var(--mf-ci-badge-bg, #0e1116);
	color: var(--mf-ci-badge-ink, #fff);

	/*
	 * REPAIR 3 — the badge box is sized in `em` against --mf-ci-size, and the text
	 * inside it carries its own smaller font-size. Both on ONE element would make the
	 * box's width and height resolve against that smaller size instead: em-recursion
	 * that collapsed the badge to a few pixels whenever --mf-ci-size was itself given
	 * in `em`, i.e. every inline placement. Hence the nested span, which the renderer
	 * always emits.
	 */
	font-size: var(--mf-ci-size, 2rem);
}

.mf-ci__badge-text {
	font-family: ui-monospace, "SF Mono", "Cascadia Mono", "Roboto Mono", monospace;
	font-size: calc(0.26em * var(--mf-ci-badge-scale, 1));
	font-weight: 700;
	line-height: 1;
	text-transform: uppercase;
	white-space: nowrap;
}

/*
 * An EMPTY badge is a plain dot, not a mistake: it is the "unread counter with no
 * number" pattern, and the renderer emits the span either way so this rule can exist.
 *
 * The dot is the smallest badge and therefore the one whose placement the wrapper
 * padding decides most visibly — it is what divb-hq#43 reported, and REPAIR 1's comment
 * is where that is worked out.
 */
.mf-ci__badge:has(.mf-ci__badge-text:empty) {
	min-width: calc(0.28em * var(--mf-ci-badge-scale, 1));
	height: calc(0.28em * var(--mf-ci-badge-scale, 1));
	padding: 0;
}

.mf-ci__badge--top-left {
	top: 0;
	left: 0;
}

.mf-ci__badge--top-right {
	top: 0;
	right: 0;
}

.mf-ci__badge--bottom-left {
	bottom: 0;
	left: 0;
}

.mf-ci__badge--bottom-right {
	right: 0;
	bottom: 0;
}

/*
 * Inline in a sentence. The renderer already forces --mf-ci-size to 1em, so there is
 * nothing to constrain here — only where the tile sits on the line.
 *
 * This POSITIVE offset is measured, not chosen, and the measurement is the interesting
 * part. `vertical-align: baseline` does not help here: the wrapper's baseline is not
 * its bottom edge but the baseline the browser propagates up from the tile's own
 * centred TEXT, which sits roughly a third of a tile above the tile's bottom. Chrome
 * propagates it whether the tile is `inline-flex` or block-level, so no amount of
 * display juggling moves it — the first attempt at this rule tried exactly that and
 * changed nothing.
 *
 * So the offset is stated against a known-good neighbour instead. On this theme, at
 * 16.8px body text, the Material Symbol's glyph bottom sits 0.167em below the baseline;
 * `0.15em` puts the tile at 0.164em, i.e. on the same line as the icon beside it. The
 * first version used `-0.2em` and the tile hung 0.493em down — visibly below its own
 * line, which is what got reported.
 *
 * The badge does NOT enter into this. Its padding moves the wrapper box, not the tile
 * relative to the propagated baseline, so badged and unbadged icons measured
 * identically — an earlier attempt to "compensate for the padding" here was correcting
 * something that never moved. Which is also why divb-hq#43 could halve that padding
 * without touching this number: re-measured at the new 0.09, badged and unbadged inline
 * icons still sit on the same line as the Material Symbol beside them.
 */
.mf-ci--inline {
	vertical-align: 0.15em;
}
