merge: 공통 버튼 눌림 효과를 반영
This commit is contained in:
@@ -1610,7 +1610,7 @@ test('the 939/940 boundary switches to the Ref-style 500px single document', asy
|
||||
await persistArtifact(page, `${basePath.slice(1)}-mobile-500`);
|
||||
});
|
||||
|
||||
test('mobile bottom controls preserve Ref navigation color, contrast, and pressed depth', async ({ page }) => {
|
||||
test('mobile bottom controls share Ref pressed geometry while their color bases vary', async ({ page }, testInfo) => {
|
||||
const state: NavigationFixture = {
|
||||
officerLevel: 5,
|
||||
permission: 2,
|
||||
@@ -1620,6 +1620,7 @@ test('mobile bottom controls preserve Ref navigation color, contrast, and presse
|
||||
nationColor: '#FFFF00',
|
||||
generalMeCalls: 0,
|
||||
operations: [],
|
||||
refreshDelayMs: 300,
|
||||
};
|
||||
await installFixture(page, state);
|
||||
await page.setViewportSize({ width: 500, height: 900 });
|
||||
@@ -1632,19 +1633,26 @@ test('mobile bottom controls preserve Ref navigation color, contrast, and presse
|
||||
return {
|
||||
backgroundColor: style.backgroundColor,
|
||||
color: style.color,
|
||||
borderTopWidth: style.borderTopWidth,
|
||||
borderLeftWidth: style.borderLeftWidth,
|
||||
borderBottomWidth: style.borderBottomWidth,
|
||||
borderBottomColor: style.borderBottomColor,
|
||||
marginTop: style.marginTop,
|
||||
fontWeight: style.fontWeight,
|
||||
height: rect.height,
|
||||
classNames: [...element.classList],
|
||||
};
|
||||
});
|
||||
const pointerDownStyle = async (selector: string) => {
|
||||
const pointerDownStyle = async (selector: string, screenshotName?: string) => {
|
||||
const target = page.locator(selector);
|
||||
const box = await target.boundingBox();
|
||||
if (!box) throw new Error(`mobile bottom control is not measurable: ${selector}`);
|
||||
await page.mouse.move(box.x + box.width / 2, box.y + box.height / 2);
|
||||
await page.mouse.down();
|
||||
const activeStyle = await buttonStyle(selector);
|
||||
if (screenshotName) {
|
||||
await page.screenshot({ path: testInfo.outputPath(screenshotName), fullPage: true });
|
||||
}
|
||||
await page.mouse.move(1, 1);
|
||||
await page.mouse.up();
|
||||
return activeStyle;
|
||||
@@ -1655,10 +1663,14 @@ test('mobile bottom controls preserve Ref navigation color, contrast, and presse
|
||||
expect(await buttonStyle(globalSelector)).toMatchObject({
|
||||
backgroundColor: 'rgb(0, 88, 44)',
|
||||
color: 'rgb(255, 255, 255)',
|
||||
borderTopWidth: '0px',
|
||||
borderLeftWidth: '1px',
|
||||
borderBottomWidth: '4px',
|
||||
borderBottomColor: 'rgb(0, 79, 40)',
|
||||
marginTop: '0px',
|
||||
fontWeight: '700',
|
||||
height: 45,
|
||||
classNames: expect.arrayContaining(['legacy-button', 'legacy-button--navigation']),
|
||||
});
|
||||
await page.locator(globalSelector).hover();
|
||||
expect(await buttonStyle(globalSelector)).toMatchObject({
|
||||
@@ -1675,19 +1687,78 @@ test('mobile bottom controls preserve Ref navigation color, contrast, and presse
|
||||
});
|
||||
|
||||
const nationTrigger = page.locator('[data-bottom-menu="nation"]');
|
||||
await expect(nationTrigger).toHaveCSS('background-color', 'rgb(255, 255, 0)');
|
||||
await expect(nationTrigger).toHaveCSS('color', 'rgb(0, 0, 0)');
|
||||
expect(await buttonStyle('[data-bottom-menu="nation"]')).toMatchObject({
|
||||
backgroundColor: 'rgb(255, 255, 0)',
|
||||
color: 'rgb(0, 0, 0)',
|
||||
borderTopWidth: '0px',
|
||||
borderLeftWidth: '1px',
|
||||
borderBottomWidth: '4px',
|
||||
borderBottomColor: 'color(srgb 0.9 0.9 0)',
|
||||
marginTop: '0px',
|
||||
fontWeight: '700',
|
||||
height: 45,
|
||||
classNames: expect.arrayContaining(['legacy-button', 'legacy-button--lumen']),
|
||||
});
|
||||
await nationTrigger.hover();
|
||||
expect(await buttonStyle('[data-bottom-menu="nation"]')).toMatchObject({
|
||||
backgroundColor: 'rgb(255, 255, 0)',
|
||||
borderBottomWidth: '3px',
|
||||
marginTop: '1px',
|
||||
height: 44,
|
||||
});
|
||||
expect(await pointerDownStyle('[data-bottom-menu="nation"]', 'mobile-bottom-nation-active.png')).toMatchObject({
|
||||
backgroundColor: 'rgb(255, 255, 0)',
|
||||
borderBottomWidth: '2px',
|
||||
marginTop: '2px',
|
||||
height: 43,
|
||||
});
|
||||
|
||||
await page.locator('[data-bottom-menu="quick"]').click();
|
||||
const quickSelector = '[data-bottom-menu="quick"]';
|
||||
expect(await buttonStyle(quickSelector)).toMatchObject({
|
||||
backgroundColor: 'rgb(33, 37, 41)',
|
||||
color: 'rgb(255, 255, 255)',
|
||||
borderTopWidth: '0px',
|
||||
borderLeftWidth: '1px',
|
||||
borderBottomWidth: '4px',
|
||||
borderBottomColor: 'rgb(30, 33, 37)',
|
||||
marginTop: '0px',
|
||||
fontWeight: '700',
|
||||
height: 45,
|
||||
classNames: expect.arrayContaining(['legacy-button', 'legacy-button--dark']),
|
||||
});
|
||||
await page.locator(quickSelector).hover();
|
||||
expect(await buttonStyle(quickSelector)).toMatchObject({
|
||||
backgroundColor: 'rgb(33, 37, 41)',
|
||||
borderBottomWidth: '3px',
|
||||
marginTop: '1px',
|
||||
height: 44,
|
||||
});
|
||||
expect(await pointerDownStyle(quickSelector)).toMatchObject({
|
||||
backgroundColor: 'rgb(33, 37, 41)',
|
||||
borderBottomWidth: '2px',
|
||||
marginTop: '2px',
|
||||
height: 43,
|
||||
});
|
||||
|
||||
await page.locator(quickSelector).click();
|
||||
const lobbySelector = '#mobile-quick-menu .lobby-link';
|
||||
await expect(page.locator(lobbySelector)).toBeVisible();
|
||||
expect(await buttonStyle(lobbySelector)).toMatchObject({
|
||||
backgroundColor: 'rgb(0, 88, 44)',
|
||||
color: 'rgb(255, 255, 255)',
|
||||
borderBottomWidth: '4px',
|
||||
borderBottomColor: 'rgb(0, 79, 40)',
|
||||
marginTop: '0px',
|
||||
fontWeight: '700',
|
||||
height: 40,
|
||||
classNames: expect.arrayContaining(['legacy-button', 'legacy-button--navigation']),
|
||||
});
|
||||
await page.locator(lobbySelector).hover();
|
||||
expect(await buttonStyle(lobbySelector)).toMatchObject({
|
||||
backgroundColor: 'rgb(0, 88, 44)',
|
||||
borderBottomWidth: '3px',
|
||||
marginTop: '1px',
|
||||
height: 39,
|
||||
});
|
||||
expect(await pointerDownStyle(lobbySelector)).toMatchObject({
|
||||
backgroundColor: 'rgb(0, 88, 44)',
|
||||
@@ -1701,9 +1772,18 @@ test('mobile bottom controls preserve Ref navigation color, contrast, and presse
|
||||
backgroundColor: 'rgb(0, 88, 44)',
|
||||
color: 'rgb(255, 255, 255)',
|
||||
borderBottomWidth: '4px',
|
||||
borderBottomColor: 'rgb(0, 79, 40)',
|
||||
marginTop: '0px',
|
||||
fontWeight: '700',
|
||||
height: 45,
|
||||
classNames: expect.arrayContaining(['legacy-button', 'legacy-button--navigation']),
|
||||
});
|
||||
await page.locator(autoRefreshSelector).hover();
|
||||
expect(await buttonStyle(autoRefreshSelector)).toMatchObject({
|
||||
backgroundColor: 'rgb(0, 88, 44)',
|
||||
borderBottomWidth: '3px',
|
||||
marginTop: '1px',
|
||||
height: 44,
|
||||
});
|
||||
expect(await pointerDownStyle(autoRefreshSelector)).toMatchObject({
|
||||
backgroundColor: 'rgb(0, 88, 44)',
|
||||
@@ -1712,6 +1792,51 @@ test('mobile bottom controls preserve Ref navigation color, contrast, and presse
|
||||
height: 43,
|
||||
});
|
||||
|
||||
const manualRefreshSelector = '[data-bottom-menu="manual-refresh"]';
|
||||
expect(await buttonStyle(manualRefreshSelector)).toMatchObject({
|
||||
backgroundColor: 'rgb(33, 37, 41)',
|
||||
color: 'rgb(255, 255, 255)',
|
||||
borderTopWidth: '0px',
|
||||
borderLeftWidth: '1px',
|
||||
borderBottomWidth: '4px',
|
||||
borderBottomColor: 'rgb(30, 33, 37)',
|
||||
marginTop: '0px',
|
||||
fontWeight: '700',
|
||||
height: 45,
|
||||
classNames: expect.arrayContaining(['legacy-button', 'legacy-button--dark']),
|
||||
});
|
||||
await page.locator(manualRefreshSelector).hover();
|
||||
expect(await buttonStyle(manualRefreshSelector)).toMatchObject({
|
||||
backgroundColor: 'rgb(33, 37, 41)',
|
||||
borderBottomWidth: '3px',
|
||||
marginTop: '1px',
|
||||
height: 44,
|
||||
});
|
||||
expect(await pointerDownStyle(manualRefreshSelector)).toMatchObject({
|
||||
backgroundColor: 'rgb(33, 37, 41)',
|
||||
borderBottomWidth: '2px',
|
||||
marginTop: '2px',
|
||||
height: 43,
|
||||
});
|
||||
await page.keyboard.press('Tab');
|
||||
await page.locator(manualRefreshSelector).focus();
|
||||
await expect
|
||||
.poll(() => page.locator(manualRefreshSelector).evaluate((element) => element.matches(':focus-visible')))
|
||||
.toBe(true);
|
||||
await expect
|
||||
.poll(() => page.locator(manualRefreshSelector).evaluate((element) => getComputedStyle(element).boxShadow))
|
||||
.not.toBe('none');
|
||||
await page.locator(manualRefreshSelector).click();
|
||||
await expect(page.locator(manualRefreshSelector)).toBeDisabled();
|
||||
expect(await buttonStyle(manualRefreshSelector)).toMatchObject({
|
||||
backgroundColor: 'rgb(33, 37, 41)',
|
||||
borderBottomWidth: '4px',
|
||||
marginTop: '0px',
|
||||
height: 45,
|
||||
});
|
||||
await expect(page.locator(manualRefreshSelector)).toHaveCSS('opacity', '0.55');
|
||||
await expect(page.locator(manualRefreshSelector)).toBeEnabled();
|
||||
|
||||
await persistArtifact(page, `${basePath.slice(1)}-mobile-bottom-ref-buttons`);
|
||||
});
|
||||
|
||||
|
||||
@@ -39,18 +39,23 @@
|
||||
}
|
||||
|
||||
/*
|
||||
* Ref Bootstrap 5.2 + Lumen button family. The modifier describes the legacy
|
||||
* semantic role; width and placement remain in the owning scoped component.
|
||||
* Ref Bootstrap 5.2 + Lumen button family. This class owns the common raised
|
||||
* edge and pressed movement. Semantic modifiers below only select face, edge,
|
||||
* and text colors; width and fixed-height compensation stay with the owner.
|
||||
* Existing semantic modifiers also opt in for backward compatibility.
|
||||
*/
|
||||
.legacy-button:is(
|
||||
.legacy-button--lumen,
|
||||
.legacy-button--primary,
|
||||
.legacy-button--secondary,
|
||||
.legacy-button--danger,
|
||||
.legacy-button--info,
|
||||
.legacy-button--navigation
|
||||
.legacy-button--navigation,
|
||||
.legacy-button--dark
|
||||
) {
|
||||
--legacy-button-bg: var(--sammo-button-primary-bg);
|
||||
--legacy-button-border: var(--sammo-button-primary-border);
|
||||
--legacy-button-color: #fff;
|
||||
min-height: 35.5px;
|
||||
margin-top: 0;
|
||||
border-color: var(--legacy-button-border);
|
||||
@@ -59,7 +64,7 @@
|
||||
border-radius: 5.25px;
|
||||
padding: 5.25px 10.5px;
|
||||
background: var(--legacy-button-bg);
|
||||
color: #fff;
|
||||
color: var(--legacy-button-color);
|
||||
line-height: 21px;
|
||||
/* Ref's framework baseline for these controls. */
|
||||
vertical-align: middle;
|
||||
@@ -85,12 +90,19 @@
|
||||
--legacy-button-border: var(--sammo-button-navigation-border);
|
||||
}
|
||||
|
||||
.legacy-button.legacy-button--dark {
|
||||
--legacy-button-bg: var(--sammo-button-dark-bg);
|
||||
--legacy-button-border: var(--sammo-button-dark-border);
|
||||
}
|
||||
|
||||
.legacy-button:is(
|
||||
.legacy-button--lumen,
|
||||
.legacy-button--primary,
|
||||
.legacy-button--secondary,
|
||||
.legacy-button--danger,
|
||||
.legacy-button--info,
|
||||
.legacy-button--navigation
|
||||
.legacy-button--navigation,
|
||||
.legacy-button--dark
|
||||
):not(:disabled, [aria-disabled='true']):hover {
|
||||
margin-top: 1px;
|
||||
border-color: var(--legacy-button-border);
|
||||
@@ -99,11 +111,28 @@
|
||||
}
|
||||
|
||||
.legacy-button:is(
|
||||
.legacy-button--lumen,
|
||||
.legacy-button--primary,
|
||||
.legacy-button--secondary,
|
||||
.legacy-button--danger,
|
||||
.legacy-button--info,
|
||||
.legacy-button--navigation
|
||||
.legacy-button--navigation,
|
||||
.legacy-button--dark
|
||||
):not(:disabled, [aria-disabled='true'])[aria-expanded='true'] {
|
||||
margin-top: 1px;
|
||||
border-color: var(--legacy-button-border);
|
||||
border-bottom-width: 3px;
|
||||
background: var(--legacy-button-bg);
|
||||
}
|
||||
|
||||
.legacy-button:is(
|
||||
.legacy-button--lumen,
|
||||
.legacy-button--primary,
|
||||
.legacy-button--secondary,
|
||||
.legacy-button--danger,
|
||||
.legacy-button--info,
|
||||
.legacy-button--navigation,
|
||||
.legacy-button--dark
|
||||
):not(:disabled, [aria-disabled='true']):active {
|
||||
margin-top: 2px;
|
||||
border-color: var(--legacy-button-border);
|
||||
@@ -112,16 +141,14 @@
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.legacy-button.legacy-button--primary:not(:disabled):active {
|
||||
background: #2d4967;
|
||||
}
|
||||
|
||||
.legacy-button:is(
|
||||
.legacy-button--lumen,
|
||||
.legacy-button--primary,
|
||||
.legacy-button--secondary,
|
||||
.legacy-button--danger,
|
||||
.legacy-button--info,
|
||||
.legacy-button--navigation
|
||||
.legacy-button--navigation,
|
||||
.legacy-button--dark
|
||||
):focus {
|
||||
border-color: var(--legacy-button-border);
|
||||
background: var(--legacy-button-bg);
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
--sammo-button-info-border: #2f89c5;
|
||||
--sammo-button-navigation-bg: #00582c;
|
||||
--sammo-button-navigation-border: #004f28;
|
||||
--sammo-button-dark-bg: #212529;
|
||||
--sammo-button-dark-border: #1e2125;
|
||||
--sammo-texture-walnut: url('https://sam-image.hided.net/game/back_walnut.jpg');
|
||||
--sammo-texture-green: url('https://sam-image.hided.net/game/back_green.jpg');
|
||||
--sammo-texture-blue: url('https://sam-image.hided.net/game/back_blue.jpg');
|
||||
|
||||
@@ -54,7 +54,7 @@ const onQuick = (item: QuickNavigationItem) => {
|
||||
>
|
||||
<div class="bottom-item">
|
||||
<button
|
||||
class="bottom-trigger ref-navigation-button"
|
||||
class="bottom-trigger legacy-button legacy-button--navigation"
|
||||
type="button"
|
||||
data-bottom-menu="global"
|
||||
:aria-expanded="openId === 'global'"
|
||||
@@ -121,7 +121,12 @@ const onQuick = (item: QuickNavigationItem) => {
|
||||
|
||||
<div class="bottom-item nation-bottom-item">
|
||||
<button
|
||||
class="bottom-trigger nation-trigger"
|
||||
class="bottom-trigger nation-trigger legacy-button legacy-button--lumen"
|
||||
:style="{
|
||||
'--legacy-button-bg': nationMenuColor,
|
||||
'--legacy-button-border': 'color-mix(in srgb, var(--nation-menu-color) 90%, #000)',
|
||||
'--legacy-button-color': nationMenuTextColor,
|
||||
}"
|
||||
type="button"
|
||||
data-bottom-menu="nation"
|
||||
:aria-expanded="openId === 'nation'"
|
||||
@@ -162,7 +167,7 @@ const onQuick = (item: QuickNavigationItem) => {
|
||||
|
||||
<div class="bottom-item">
|
||||
<button
|
||||
class="bottom-trigger quick-trigger"
|
||||
class="bottom-trigger quick-trigger legacy-button legacy-button--dark"
|
||||
type="button"
|
||||
data-bottom-menu="quick"
|
||||
:aria-expanded="openId === 'quick'"
|
||||
@@ -192,7 +197,7 @@ const onQuick = (item: QuickNavigationItem) => {
|
||||
</template>
|
||||
<li class="bottom-lobby" role="none">
|
||||
<button
|
||||
class="quick-link lobby-link ref-navigation-button"
|
||||
class="quick-link lobby-link legacy-button legacy-button--navigation"
|
||||
type="button"
|
||||
role="menuitem"
|
||||
@click="emit('lobby')"
|
||||
@@ -205,7 +210,7 @@ const onQuick = (item: QuickNavigationItem) => {
|
||||
|
||||
<div class="bottom-refresh-controls">
|
||||
<button
|
||||
class="bottom-trigger auto-refresh-trigger ref-navigation-button"
|
||||
class="bottom-trigger auto-refresh-trigger legacy-button legacy-button--navigation"
|
||||
:class="{ active: realtimeEnabled }"
|
||||
type="button"
|
||||
data-bottom-menu="auto-refresh"
|
||||
@@ -216,7 +221,7 @@ const onQuick = (item: QuickNavigationItem) => {
|
||||
<strong>{{ realtimeEnabled ? 'ON' : 'OFF' }}</strong>
|
||||
</button>
|
||||
<button
|
||||
class="bottom-trigger manual-refresh-trigger"
|
||||
class="bottom-trigger manual-refresh-trigger legacy-button legacy-button--dark"
|
||||
type="button"
|
||||
data-bottom-menu="manual-refresh"
|
||||
aria-label="직접 갱신"
|
||||
@@ -267,10 +272,7 @@ const onQuick = (item: QuickNavigationItem) => {
|
||||
box-sizing: border-box;
|
||||
width: 125px;
|
||||
height: 45px;
|
||||
border: 1px solid #1f1712;
|
||||
padding: 6px 4px;
|
||||
background: #302016 var(--sammo-texture-walnut);
|
||||
color: #fff;
|
||||
font-family: inherit;
|
||||
font-size: 16px;
|
||||
line-height: 1.5;
|
||||
@@ -278,16 +280,6 @@ const onQuick = (item: QuickNavigationItem) => {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.nation-trigger {
|
||||
border-color: color-mix(in srgb, var(--nation-menu-color) 85%, #000);
|
||||
background: var(--nation-menu-color);
|
||||
color: var(--nation-menu-text-color);
|
||||
}
|
||||
|
||||
.quick-trigger {
|
||||
background: #212529;
|
||||
}
|
||||
|
||||
.auto-refresh-trigger {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@@ -310,7 +302,6 @@ const onQuick = (item: QuickNavigationItem) => {
|
||||
|
||||
.manual-refresh-trigger {
|
||||
padding: 0;
|
||||
background: #212529;
|
||||
font-size: 22px;
|
||||
line-height: 1;
|
||||
}
|
||||
@@ -321,51 +312,13 @@ const onQuick = (item: QuickNavigationItem) => {
|
||||
opacity: 0.55;
|
||||
}
|
||||
|
||||
.bottom-trigger:hover,
|
||||
.bottom-trigger:focus-visible,
|
||||
.bottom-trigger[aria-expanded='true'] {
|
||||
filter: brightness(1.14);
|
||||
}
|
||||
|
||||
.bottom-trigger:active {
|
||||
filter: brightness(0.82);
|
||||
}
|
||||
|
||||
/*
|
||||
* Ref's btn-sammo-base2 is a Lumen-style navigation button. Its lower edge
|
||||
* shortens while the control moves down, so hover and pointer-down visibly
|
||||
* feel pressed instead of only changing brightness.
|
||||
*/
|
||||
.ref-navigation-button {
|
||||
border-color: var(--sammo-button-navigation-border);
|
||||
border-style: solid;
|
||||
border-width: 0 1px 4px;
|
||||
background: var(--sammo-button-navigation-bg);
|
||||
color: #fff;
|
||||
font-weight: 700;
|
||||
transition:
|
||||
color 0.15s,
|
||||
background-color 0.15s,
|
||||
border-color 0.15s,
|
||||
box-shadow 0.15s;
|
||||
}
|
||||
|
||||
.bottom-trigger.ref-navigation-button:hover,
|
||||
.bottom-trigger.ref-navigation-button:focus-visible,
|
||||
.bottom-trigger.ref-navigation-button[aria-expanded='true'] {
|
||||
.bottom-trigger.legacy-button:not(:disabled, [aria-disabled='true']):hover,
|
||||
.bottom-trigger.legacy-button:not(:disabled, [aria-disabled='true'])[aria-expanded='true'] {
|
||||
height: 44px;
|
||||
margin-top: 1px;
|
||||
border-bottom-width: 3px;
|
||||
background: var(--sammo-button-navigation-bg);
|
||||
filter: none;
|
||||
}
|
||||
|
||||
.bottom-trigger.ref-navigation-button:active {
|
||||
.bottom-trigger.legacy-button:not(:disabled, [aria-disabled='true']):active {
|
||||
height: 43px;
|
||||
margin-top: 2px;
|
||||
border-bottom-width: 2px;
|
||||
background: var(--sammo-button-navigation-bg);
|
||||
filter: none;
|
||||
}
|
||||
|
||||
.dropup-caret {
|
||||
@@ -420,11 +373,7 @@ const onQuick = (item: QuickNavigationItem) => {
|
||||
min-height: 34px;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
border: 0;
|
||||
border-radius: 0;
|
||||
padding: 5px 16px;
|
||||
background: transparent;
|
||||
color: #fff;
|
||||
font-family: inherit;
|
||||
font-size: 16px;
|
||||
line-height: 1.5;
|
||||
@@ -434,10 +383,17 @@ const onQuick = (item: QuickNavigationItem) => {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.quick-link:not(.legacy-button) {
|
||||
border: 0;
|
||||
border-radius: 0;
|
||||
background: transparent;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.bottom-popup :deep(.main-menu-link:hover),
|
||||
.bottom-popup :deep(.main-menu-link:focus-visible),
|
||||
.quick-link:hover,
|
||||
.quick-link:focus-visible {
|
||||
.quick-link:not(.legacy-button):hover,
|
||||
.quick-link:not(.legacy-button):focus-visible {
|
||||
background: #353535;
|
||||
}
|
||||
|
||||
@@ -459,28 +415,23 @@ const onQuick = (item: QuickNavigationItem) => {
|
||||
|
||||
.lobby-link {
|
||||
width: auto;
|
||||
height: 40px;
|
||||
min-height: 40px;
|
||||
justify-content: center;
|
||||
margin-right: auto;
|
||||
margin-left: auto;
|
||||
border-color: var(--sammo-button-navigation-border);
|
||||
border-style: solid;
|
||||
border-width: 0 1px 4px;
|
||||
border-radius: 6px;
|
||||
padding: 6px 12px;
|
||||
background: var(--sammo-button-navigation-bg);
|
||||
}
|
||||
|
||||
.lobby-link:hover,
|
||||
.lobby-link:focus-visible {
|
||||
margin-top: 1px;
|
||||
border-bottom-width: 3px;
|
||||
background: var(--sammo-button-navigation-bg);
|
||||
.lobby-link:hover {
|
||||
height: 39px;
|
||||
min-height: 39px;
|
||||
}
|
||||
|
||||
.lobby-link:active {
|
||||
margin-top: 2px;
|
||||
border-bottom-width: 2px;
|
||||
background: var(--sammo-button-navigation-bg);
|
||||
height: 38px;
|
||||
min-height: 38px;
|
||||
}
|
||||
|
||||
@media (max-width: 939.98px) {
|
||||
|
||||
@@ -40,20 +40,28 @@ the same label.
|
||||
| Bootstrap/Lumen danger | `.legacy-button.legacy-button--danger` | destructive action only when Ref uses `variant="danger"` |
|
||||
| Bootstrap/Lumen info | `.legacy-button.legacy-button--info` | informational or edit action only when Ref uses `variant="info"` |
|
||||
| `btn-sammo-base2` navigation | `.legacy-button.legacy-button--navigation` | page back/close and paired reload controls |
|
||||
| Bootstrap/Lumen dark | `.legacy-button.legacy-button--dark` | dark navigation or utility control when Ref uses `btn-dark` |
|
||||
| dynamic Lumen color | `.legacy-button.legacy-button--lumen` | nation or scenario color supplied through the shared face/edge/text custom properties |
|
||||
| page-specific/native control | feature-namespaced scoped class | only when Ref computed geometry or interaction differs from the Bootstrap/Lumen family |
|
||||
|
||||
The base class supplies accessible link/button normalization and the historical
|
||||
`base1` fallback used by already measured screens. New Bootstrap/Lumen controls
|
||||
must add an explicit semantic modifier; do not infer a mutation role from a
|
||||
label such as `구입` in page CSS. A disabled control keeps its semantic color
|
||||
and uses the shared opacity/cursor state. Hover and active use the Ref Lumen
|
||||
bottom-border movement rather than an unrelated brightness filter.
|
||||
`base1` fallback used by already measured screens. The Lumen family selector
|
||||
owns the `0 1px 4px` raised edge and the shared hover/active movement. Its
|
||||
semantic modifiers only assign `--legacy-button-bg`, `--legacy-button-border`,
|
||||
and `--legacy-button-color`; custom nation colors use the explicit
|
||||
`.legacy-button--lumen` structure class and assign those same properties. New
|
||||
Bootstrap/Lumen controls must add an explicit family or semantic modifier; do
|
||||
not infer a mutation role from a label such as `구입` in page CSS. A disabled
|
||||
control keeps its semantic color and uses the shared opacity/cursor state.
|
||||
Hover and active use the Ref Lumen bottom-border movement rather than an
|
||||
unrelated brightness filter.
|
||||
|
||||
Only layout belongs in the SFC: width, grid column, margins required by the
|
||||
page, and breakpoint-specific placement. Color, border, font weight,
|
||||
hover/focus/active, and disabled presentation belong in
|
||||
`legacy-controls.css` when the Ref family is shared. Generic `.btn`, `button`,
|
||||
or `.primary` rules must not be promoted globally.
|
||||
Only layout belongs in the SFC: width, grid column, fixed-height compensation,
|
||||
margins required by the page, and breakpoint-specific placement. Color base
|
||||
variables may be supplied by the owner for dynamic nation/scenario colors, but
|
||||
border construction, font weight, hover/focus/active, and disabled presentation
|
||||
belong in `legacy-controls.css` when the Ref family is shared. Generic `.btn`,
|
||||
`button`, or `.primary` rules must not be promoted globally.
|
||||
|
||||
## Class naming
|
||||
|
||||
|
||||
Reference in New Issue
Block a user