Files
HMDesign/packages/center-graphic/src/components/CenterInformationDisplay.css
T

600 lines
17 KiB
CSS

/*
* CENTER Information Display — Reference Implementation styles.
*
* Every length is expressed in design units (u) via calc(N * var(--cid-u)), where the
* numbers N are the normalised values measured from the Source SVGs and recorded in
* verification/center-information-display/SOURCE-ANALYSIS.md.
*
* Setting --cid-u is how a consumer chooses a rendering scale. The Source itself does
* not declare an absolute size for 1 u (Inventory FU-2).
*/
.cid-scope {
--cid-u: 1px;
--cid-font: var(--center-font-family, 'Noto Sans KR', 'Apple SD Gothic Neo', 'Malgun Gothic', sans-serif);
}
/* ── Shared card ──────────────────────────────────────────────────────── */
.cid-card {
min-width: 0;
box-sizing: border-box;
width: var(--cid-card-width, fit-content);
padding: calc(2 * var(--cid-u));
border-radius: calc(8 * var(--cid-u));
background: #ffffff;
box-shadow:
calc(4 * var(--cid-u)) calc(4 * var(--cid-u)) calc(4 * var(--cid-u)) rgba(0, 0, 0, 0.25);
font-family: var(--cid-font);
font-feature-settings: normal;
text-rendering: geometricPrecision;
}
.cid-card__header {
display: flex;
align-items: center;
justify-content: center;
height: var(--cid-header-height, calc(40.654 * var(--cid-u)));
padding: 0 calc(10 * var(--cid-u));
overflow: hidden;
/* The band's top radius is the one card value that does NOT scale with the family:
both export scales carry the same raw 8.133 px, so it is 5.7921 u in the box family
and 5.5894 u in the table family. Both are Source-measured, neither is derived. */
border-radius: var(--cid-header-radius, calc(5.7921 * var(--cid-u)))
var(--cid-header-radius, calc(5.7921 * var(--cid-u))) 0 0;
background: linear-gradient(90deg, var(--cid-header-from), var(--cid-header-to));
}
.cid-card__header > span {
min-width: 0;
text-overflow: ellipsis;
color: #ffffff;
font-size: var(--cid-header-size, calc(27.4 * var(--cid-u)));
font-weight: 700;
line-height: 1;
white-space: nowrap;
overflow: hidden;
-webkit-text-stroke: calc(2 * var(--cid-u)) rgba(0, 0, 0, 0.5);
paint-order: stroke fill;
}
.cid-card__body {
box-sizing: border-box;
margin-top: calc(2 * var(--cid-u));
background: #ffffff;
}
/*
* The body frame is NOT a CSS border: Chrome snaps used border-width to a coarse
* grid (calc(4 * 1.4041px) resolves to 5.333px, not 5.6164px), which breaks
* sub-pixel parity with the Source. Padding + a layered inner surface is exact.
*/
.cid-card__body--list,
.cid-card__body--emphasis {
position: relative;
border-radius: 0 0 calc(6 * var(--cid-u)) calc(6 * var(--cid-u));
background: var(--cid-border);
}
/* The Source paints the inner content surface as a plain, UNROUNDED <rect> inside the
rounded frame — its square corners clear the 6 u curve, so no rounding is applied. */
.cid-card__body--list::before,
.cid-card__body--emphasis::before {
content: '';
position: absolute;
inset: calc(4 * var(--cid-u));
z-index: 0;
border-radius: 0;
background: #ffffff;
}
.cid-card__body--list > *,
.cid-card__body--emphasis > * {
position: relative;
z-index: 1;
}
.cid-card__body--table {
padding: calc(2 * var(--cid-u));
border-radius: 0 0 calc(6 * var(--cid-u)) calc(6 * var(--cid-u));
background: var(--cid-border);
overflow: hidden;
}
/* ── Bullet badge ─────────────────────────────────────────────────────── */
.cid-badge {
box-sizing: border-box;
position: relative;
/* Confines the sheen's plus-lighter blending to the badge's own surface. */
isolation: isolate;
flex: 0 0 auto;
width: calc(20 * var(--cid-u));
height: calc(20 * var(--cid-u));
border-radius: 50%;
background: var(--cid-badge);
/* The white ring is an inset shadow, not a border: border-width is snapped by the
engine and a bordered background also fails to paint inside foreignObject. */
box-shadow:
inset 0 0 0 calc(1.093 * var(--cid-u)) #ffffff,
calc(1.093 * var(--cid-u)) calc(1.093 * var(--cid-u))
calc(2.186 * var(--cid-u)) rgba(0, 0, 0, 0.25);
}
/*
* The Source overlays a 25% white diagonal sheen on the badge.
*
* The Source gradient is userSpaceOnUse from (29.2028, 94.3404) to (43.7721, 114.161)
* on a badge of centre (36.5078, 104.822) and diameter 28.082 raw. Re-solved for CSS,
* whose gradient line is sized to the box, that vector is 143.682deg and its four Source
* stops (0 / 0.35 / 0.65 / 1) land at 17.467 / 39.398 / 58.196 / 80.126 percent.
*
* The Source composites it with `mix-blend-mode: plus-lighter`, which on a non-zero
* channel is materially brighter than normal alpha compositing (badge blue 0x41:
* 128.75 additive vs 112.5 normal), so the blend mode is reproduced rather than
* approximated. It is painted BEFORE the chevron, as in the Source, so the sheen
* passes under the white glyph instead of tinting it.
*/
.cid-badge::before {
content: '';
position: absolute;
inset: 0;
z-index: 0;
border-radius: 50%;
background: linear-gradient(
143.682deg,
rgba(255, 255, 255, 0.25) 17.467%,
rgba(255, 255, 255, 0) 39.398%,
rgba(255, 255, 255, 0) 58.196%,
rgba(255, 255, 255, 0.25) 80.126%
);
mix-blend-mode: plus-lighter;
pointer-events: none;
}
.cid-badge__chevron {
position: absolute;
inset: 0;
z-index: 1;
width: calc(20 * var(--cid-u));
height: calc(20 * var(--cid-u));
filter: drop-shadow(
calc(1.093 * var(--cid-u)) calc(1.093 * var(--cid-u))
calc(3.278 * var(--cid-u)) rgba(0, 37, 89, 0.65)
);
}
/* ── Form 1a — list body ──────────────────────────────────────────────── */
.cid-card__body--list,
.cid-card__body--emphasis {
padding: calc(15.756 * var(--cid-u)) calc(14 * var(--cid-u))
calc(13.56 * var(--cid-u)) calc(14 * var(--cid-u));
}
/*
* 강조형 1's content area measures 80 u tall against the list form's own rule predicting
* 78.834 u. The stack above the remainder is fully constrained and font-independent —
* 11.756 u lead-in (confirmed by the badge, which centres on line 1), 28.488 u primary
* line, 0.542 u secondary offset, 28.488 u secondary line — so the 1.166 u difference
* lands entirely in the trailing pad: 10.726 u of content pad plus the 4 u frame.
* One Source sample, so REFERENCE_OBSERVATION, not a derived rule.
*/
.cid-card__body--emphasis {
padding-bottom: calc(14.726 * var(--cid-u));
}
.cid-item {
display: flex;
align-items: flex-start;
}
.cid-item + .cid-item {
margin-top: calc(7.512 * var(--cid-u));
}
.cid-item > .cid-badge {
margin-top: calc(4.244 * var(--cid-u));
}
.cid-item__text {
flex: 1 1 0;
margin-left: calc(10 * var(--cid-u));
min-width: 0;
}
.cid-item__primary {
margin: 0;
color: var(--cid-text);
font-size: calc(23.7 * var(--cid-u));
letter-spacing: calc(-0.90642333984375 * var(--cid-u));
font-weight: 700;
line-height: calc(28.488 * var(--cid-u));
}
/* 강조형 1 measures a 29.03 u advance from the primary line to the secondary one,
0.542 u more than the primary line-height. */
.cid-item__secondary {
margin: calc(0.542 * var(--cid-u)) 0 0;
color: var(--cid-text);
font-size: calc(21.49 * var(--cid-u));
letter-spacing: calc(-0.8260262229225852 * var(--cid-u));
font-weight: 700;
line-height: calc(28.488 * var(--cid-u));
}
.cid-item__line {
display: block;
}
/* ── Form 1b — definition body ────────────────────────────────────────── */
.cid-card__body--definition {
padding: calc(10 * var(--cid-u)) 0 0 0;
}
.cid-def {
margin-bottom: calc(12.21 * var(--cid-u));
}
.cid-def__chip {
box-sizing: border-box;
max-width: 100%;
display: flex;
align-items: center;
width: fit-content;
height: calc(28 * var(--cid-u));
margin-left: calc(8 * var(--cid-u));
padding-left: calc(4 * var(--cid-u));
padding-right: calc(81.8 * var(--cid-u));
/* information-box.md §5.3/§5.5: pill relation, radius = height / 2 = 14 u
(Confirmed across five chip widths). */
border-radius: calc(14 * var(--cid-u));
background: linear-gradient(
to right,
#dce7f6 29.54%,
rgba(245, 249, 255, 0) 100%
);
}
.cid-def__label {
margin-left: calc(4.44 * var(--cid-u));
color: #000000;
font-size: calc(20 * var(--cid-u));
font-weight: 700;
line-height: calc(19.12 * var(--cid-u));
white-space: nowrap;
-webkit-text-stroke: calc(2 * var(--cid-u)) #ffffff;
paint-order: stroke fill;
}
.cid-def__value {
margin: calc(2.12 * var(--cid-u)) 0 0 calc(36.5 * var(--cid-u));
color: #000000;
font-size: calc(21.79 * var(--cid-u));
font-weight: 500;
line-height: calc(32.049 * var(--cid-u));
}
.cid-def__line {
display: block;
}
.cid-def__bullets {
margin: calc(2.12 * var(--cid-u)) 0 0 0;
padding: 0;
list-style: none;
}
.cid-def__bullets > li {
position: relative;
margin-left: calc(36.5 * var(--cid-u));
color: #000000;
font-size: calc(21.79 * var(--cid-u));
font-weight: 500;
line-height: calc(32.049 * var(--cid-u));
}
.cid-def__bullets > li + li {
margin-top: calc(7.834 * var(--cid-u));
}
.cid-def__bullets > li::before {
content: '\2022';
position: absolute;
left: calc(-18.5 * var(--cid-u));
}
/* ── Form 2 — table body ──────────────────────────────────────────────── */
.cid-card--table {
--cid-header-size: calc(26.66 * var(--cid-u));
--cid-header-height: calc(39.231 * var(--cid-u));
--cid-header-radius: calc(5.5894 * var(--cid-u));
}
.cid-table {
display: grid;
grid-template-columns: calc(133.299 * var(--cid-u)) minmax(0, 1fr);
gap: calc(2 * var(--cid-u));
background: var(--cid-border);
}
.cid-table__row {
display: contents;
}
.cid-table__label {
display: flex;
align-items: center;
justify-content: center;
padding: 0 calc(4 * var(--cid-u));
background: #dce7f6;
color: #001a41;
font-size: calc(20 * var(--cid-u));
font-weight: 700;
line-height: calc(26.116 * var(--cid-u));
text-align: center;
}
/* Source 테이블형 rounds ONLY the last row's value cell, by 4 u, so the frame's own
6 u bottom-right curve stays visible through it. The bottom-left label cell is a
square rect in the Source and is left square here. */
.cid-table__row:last-child .cid-table__value {
border-bottom-right-radius: calc(4 * var(--cid-u));
}
.cid-table__value {
min-width: 0;
box-sizing: border-box;
padding: calc(8.5 * var(--cid-u)) calc(10 * var(--cid-u))
calc(9.19 * var(--cid-u)) calc(33.89 * var(--cid-u));
background: #ffffff;
}
.cid-table__item {
position: relative;
margin: 0;
color: #000000;
font-size: calc(21.79 * var(--cid-u));
font-weight: 500;
line-height: calc(26.116 * var(--cid-u));
}
.cid-table__item + .cid-table__item {
margin-top: calc(8.248 * var(--cid-u));
}
.cid-table__item::before {
content: '\2022';
position: absolute;
left: calc(-20.32 * var(--cid-u));
}
.cid-table__line {
display: block;
}
/* ── Form 3 — emphasis ────────────────────────────────────────────────── */
.cid-emphasis {
display: flex;
align-items: stretch;
width: fit-content;
max-width: 100%;
}
.cid-card--emphasis {
position: relative;
z-index: 1;
flex: 0 0 auto;
}
.cid-panel {
position: relative;
z-index: 0;
display: flex;
align-items: center;
box-sizing: border-box;
flex: 0 0 auto;
width: var(--cid-panel-width, calc(447.5 * var(--cid-u)));
min-width: 0;
margin: calc(0.178 * var(--cid-u)) 0 calc(0.178 * var(--cid-u)) calc(-4 * var(--cid-u));
padding-left: calc(20 * var(--cid-u));
font-family: var(--cid-font);
}
.cid-panel::before {
content: '';
position: absolute;
inset: 0;
z-index: -1;
border-radius: calc(8.688 * var(--cid-u));
background: linear-gradient(90deg, #0054cc 0%, rgba(0, 27, 66, 0) 100%);
opacity: 0.85;
}
.cid-panel__arrow {
flex: 0 0 auto;
width: calc(53.676 * var(--cid-u));
height: calc(40.583 * var(--cid-u));
margin-right: calc(14.41 * var(--cid-u));
overflow: visible;
fill: #0044a4;
stroke: #ffffff;
stroke-width: calc(4 * var(--cid-u));
stroke-linejoin: miter;
paint-order: stroke fill;
filter: drop-shadow(0 calc(4 * var(--cid-u)) calc(4 * var(--cid-u)) rgba(0, 0, 0, 0.25));
}
/* With no arrow the text sits 21.23 u from the panel's left edge (강조형2). */
.cid-panel:not(:has(.cid-panel__arrow)) {
padding-left: calc(21.23 * var(--cid-u));
}
.cid-panel__text {
min-width: 0;
max-width: 100%;
margin: 0;
color: #ffffff;
font-size: var(--cid-emphasis-size, calc(33.742 * var(--cid-u)));
font-weight: 700;
line-height: calc(36.322 * var(--cid-u));
white-space: nowrap;
-webkit-text-stroke: calc(2.896 * var(--cid-u)) #0054cc;
paint-order: stroke fill;
}
.cid-panel__line {
display: block;
}
/* ── Mini table (강조형2 left card) ───────────────────────────────────── */
.cid-card__body--emphasis:has(.cid-metrics) {
padding: calc(4 * var(--cid-u));
}
.cid-metrics {
display: grid;
grid-template-columns: calc(91.22 * var(--cid-u)) minmax(0, 1fr);
gap: calc(2 * var(--cid-u));
background: var(--cid-border);
}
.cid-metrics__row {
display: contents;
}
.cid-metrics__label {
display: flex;
align-items: center;
justify-content: center;
height: calc(37.093 * var(--cid-u));
background: #dce7f6;
color: #001a41;
font-size: calc(20 * var(--cid-u));
font-weight: 700;
line-height: calc(19.12 * var(--cid-u));
}
/* Information-only renderer calibration, not Canonical size/weight/tracking tokens.
* Source-supported Hangul ink: term/table label 18.52 u, metric label 18.58 u,
* primary 22.22 u, secondary 20.19 u (existing ±3% height / ±2% width gates).
* Controlled probes under the resolved Noto face established the sizes above.
* Term/label tracking preserves the previous Hangul advance; word spacing preserves
* the previous space advance. Primary/secondary tracking preserves the complete
* representative Source-string advance, including spaces and mixed-script content.
* Fixed line boxes and all existing component geometry remain unchanged.
* Evidence: verification/center-information-typography-remediation/.
* Font binary approval and complete role mappings remain TBD.
*/
.cid-def__label,
.cid-table__label,
.cid-metrics__label {
letter-spacing: calc(-0.809600830078125 * var(--cid-u));
word-spacing: calc(0.563201904296875 * var(--cid-u));
}
.cid-metrics__value {
min-width: 0;
display: flex;
align-items: center;
height: calc(37.093 * var(--cid-u));
padding-left: calc(10.667 * var(--cid-u));
background: #ffffff;
color: #001a41;
font-size: calc(21.05 * var(--cid-u));
font-weight: 400;
line-height: 1;
white-space: pre;
}
/* Source-confirmed weight split: only the result value and the delta are bold. */
.cid-metrics__from {
font-weight: 400;
}
.cid-metrics__to {
font-weight: 700;
}
.cid-metrics__delta {
color: #ff0000;
font-weight: 700;
}
/* User-confirmed overflow policy. Each authored line stays a separate line;
long dynamic strings do not create extra rows or expand an owned region. */
.cid-item__line,
.cid-def__line,
.cid-def__label,
.cid-def__bullet-line,
.cid-table__line,
.cid-table__label > span,
.cid-metrics__label > span,
.cid-metrics__run,
.cid-panel__line {
display: block;
min-width: 0;
max-width: 100%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.cid-def__value,
.cid-table__label,
.cid-metrics__label { min-width: 0; }
/* ── Reference page demo chrome (not part of the Component contract) ───── */
.cid-demo {
display: grid;
gap: 24px;
}
.cid-demo__block > header {
display: flex;
align-items: baseline;
gap: 10px;
flex-wrap: wrap;
margin-bottom: 12px;
}
.cid-demo__block > header strong {
color: var(--color-action-primary);
font-size: 14px;
line-height: 20px;
}
.cid-demo__block > header span {
color: var(--color-fg-secondary);
font-size: 12px;
line-height: 18px;
}
.cid-demo__stage {
display: flex;
flex-wrap: wrap;
gap: 28px;
align-items: flex-start;
padding: 20px 20px 24px;
border: 1px solid var(--color-stroke-subtle);
border-radius: 4px;
background: #eceff3;
overflow-x: auto;
}
.cid-demo__state {
display: grid;
gap: 8px;
justify-items: start;
}
.cid-demo__tag {
color: var(--color-fg-secondary);
font-size: 11px;
letter-spacing: 0.08em;
}