/*
 * Palette sampled from the live order form (spec §9.1) so the two pages read
 * as one flow. Mobile only — no desktop breakpoint by design.
 */
.bs-app {
	--bs-pink: #EC4F81;
	--bs-purple: #8B63C9;
	--bs-blush: #FDEDF0;
	--bs-outline: #F9CAD3;
	--bs-base: #FFFFFF;
	--bs-text: #333333;

	max-width: 520px;
	margin: 0 auto;
	/* 96px is a static fallback for before JS has measured anything; JS then
	   sets --bs-nav-h to the fixed nav bar's own real height (plus a margin)
	   so this padding always matches it, on any device (safe-area inset, font
	   scaling, the nav's own size changing) — see the "layer order" fix,
	   2026-09-12, where content was rendering underneath the bar. */
	padding: 0 16px var(--bs-nav-h, 96px);
	color: var(--bs-text);
	font-family: "Zen Kaku Gothic New", "Noto Sans JP", -apple-system, sans-serif;
	background: var(--bs-base);
	line-height: 1.7;
}


/* `hidden` must win over the display rules below it. */
.bs-app [hidden],
.bs-loading[hidden] { display: none !important; }

.bs-app *,
.bs-app *::before,
.bs-app *::after { box-sizing: border-box; }

/* ---------- hero ----------
 * The client supplied a reference for this band (2026-09-07) and flagged the
 * old one for 「段落の幅感」: the two title lines were set narrow and centred in
 * a tall box, which read as a cramped column rather than a banner. It now runs
 * edge to edge with the lines close together, デザイン picked out in pink, and
 * a few drawn sparkles.
 */
.bs-hero {
	position: relative;
	margin: 0 -16px 16px;
	padding: 22px 16px 18px;
	text-align: center;
	overflow: hidden;
	background: linear-gradient(180deg, #FDE9F0 0%, #FCF3F6 55%, #FFFFFF 100%);
}
.bs-hero__title {
	margin: 0 0 6px;
	font-size: 27px;
	line-height: 1.35;
	font-weight: 700;
	color: #4A3B42;
	letter-spacing: .06em;
}
.bs-hero__title em {
	font-style: normal;
	color: var(--bs-pink);
}
.bs-hero__heart {
	color: var(--bs-pink);
	font-weight: 400;
	margin-left: .12em;
}
.bs-hero__sub {
	margin: 0;
	font-size: 12px;
	letter-spacing: .04em;
	color: #6B5A62;
}

/* Four-point sparkles: two crossed gradients pinched to a star. */
.bs-hero__sparkle {
	position: absolute;
	width: 14px;
	height: 14px;
	pointer-events: none;
	background:
		radial-gradient(ellipse 50% 8% at 50% 50%, #F4B8CE 0%, rgba(244,184,206,0) 70%),
		radial-gradient(ellipse 8% 50% at 50% 50%, #F4B8CE 0%, rgba(244,184,206,0) 70%);
}
.bs-hero__sparkle--a { top: 26%; left: 12%; width: 18px; height: 18px; }
.bs-hero__sparkle--b { top: 58%; left: 22%; width: 10px; height: 10px; }
.bs-hero__sparkle--c { top: 22%; right: 14%; width: 12px; height: 12px; }
.bs-hero__sparkle--d { top: 56%; right: 24%; width: 16px; height: 16px; }

@media (max-width: 360px) {
	.bs-hero__title { font-size: 24px; }
	.bs-hero__sparkle { display: none; }
}

/* ---------- step rail ---------- */
.bs-steps {
	display: flex;
	gap: 4px;
	margin: 0 0 18px;
	padding: 0;
	list-style: none;
	font-size: 11px;
}
.bs-steps li {
	flex: 1;
	padding: 7px 2px;
	text-align: center;
	border-radius: 999px;
	border: 1px solid var(--bs-outline);
	color: var(--bs-pink);
	background: var(--bs-base);
	white-space: nowrap;
}
.bs-steps li.is-active {
	background: var(--bs-pink);
	border-color: var(--bs-pink);
	color: #fff;
	font-weight: 700;
}
.bs-steps li.is-done { background: var(--bs-blush); }

/* ---------- stage ---------- */
/*
 * The stage sticks to the top of the viewport. Part grids are long, and if the
 * bottle scrolls away the customer taps an option and cannot see what changed —
 * they have to scroll back up after every single choice.
 */
.bs-stage-card {
	position: sticky;
	top: 0;
	z-index: 30;
	margin: 0 0 16px;
	padding: 10px 12px;
	background: var(--bs-base);
	border: 1px solid var(--bs-outline);
	border-radius: 16px;
	box-shadow: 0 6px 16px -10px rgba(0, 0, 0, .35);
}
.bs-stage {
	position: relative;
	/* Client, 2026-09-04, originally asked for 6-7 tenths of the screen
	   (「スマホの画面配分でいうと6割〜7割ほど」); client, 2026-09-12, after actually
	   testing that on a phone, asked for the opposite — the bottle taking up
	   most of the screen left too little room to see the option grid below it,
	   so picking anything meant scrolling constantly
	   (「プレビューボトルの範囲が大きく...操作しにくい」「ボトルゾーンを狭くして
	   下部のリボンなどは2つか3つは一画面に視認できるようにしたい」). Shrunk so 2-3
	   option rows are visible under it on one screen; the stage is still sticky,
	   so the bottle stays in view while options are picked. */
	height: 38vh;
	/* dvh, where supported, so iOS Safari's collapsing URL bar cannot leave the
	   stage taller than the screen it is measured against. vh stays as the
	   fallback for older browsers. */
	height: 38dvh;
	max-height: none;
	max-width: 100%;
	aspect-ratio: 3 / 4;
	width: auto;
	margin: 0 auto;
	overflow: hidden;
	border-radius: 10px;
	background: #fafafa;
}
/*
 * Confirmation step: nothing is being chosen any more, so the preview takes the
 * screen. The client asked for the finished bottle to be shown as large as
 * possible here, while the smaller stage stays for the selection steps.
 */
.bs-app.is-final .bs-stage {
	/* Taller and narrower than the selection stage. The bottle is ~3.5x taller
	   than it is wide, so a 3:4 frame wastes most of its width; matching the
	   bottle's own proportions is what actually makes it big on a phone.
	   Sized off the height so the frame follows the screen, then capped by
	   width so it can never overflow a narrow phone. */
	height: 76vh;
	height: 76dvh;
	max-height: none;
	max-width: 100%;
	aspect-ratio: 5 / 8;
}
.bs-app.is-final .bs-stage-card {
	position: static;
}
.bs-layer {
	position: absolute;
	inset: 0;
	pointer-events: none;
}
/*
 * The printed design. Rendered through canvas rather than as a CSS background
 * because it has to be projected onto the curve of the bottle and shaded; a
 * flat background reads as a sticker stuck on the photo.
 */
.bs-layer--wrap {
	inset: 0;
	width: 100%;
	height: 100%;
	z-index: 32;
}
/*
 * The bottle is positioned like a part, not stretched to the stage: every
 * option is sized as a fraction of the bottle, so the bottle needs a real
 * width the script can set (and grow on the confirmation step).
 */
.bs-layer--bottle {
	position: absolute;
	inset: auto;
	z-index: 20;
	height: auto;
	transform: translate(-50%, -50%);
	transform-origin: center center;
}
/*
 * No z-index here on purpose. A positioned element WITH z-index creates a
 * stacking context, which would trap every part below the wrap canvas. Left as
 * auto, each part's own z competes directly with the glass (20) and the printed
 * design (32) — so the neck cover goes under the print and the label on top.
 */
.bs-layer--parts { z-index: auto; }

.bs-part {
	position: absolute;
	transform-origin: center center;
	pointer-events: none;
	will-change: transform;
}

/* ---------- section chrome ---------- */
.bs-ribbon {
	position: relative;
	display: block;
	margin: 24px 0 14px;
	padding: 8px 18px;
	font-size: 15px;
	line-height: 1.5;
	font-weight: 700;
	color: #fff;
	text-align: center;
	background: var(--bs-purple);
	border-radius: 999px;
}
.bs-sub {
	margin: 18px 0 8px;
	font-size: 13px;
	font-weight: 700;
	color: var(--bs-purple);
}

.bs-note {
	margin: 0 0 14px;
	padding: 12px 14px;
	background: #FFFBFC;
	border: 1px solid var(--bs-outline);
	border-radius: 12px;
	font-size: 12px;
}
.bs-note ul { margin: 0; padding-left: 16px; list-style: none; }
.bs-note li { position: relative; padding-left: 12px; }
.bs-note li::before {
	content: "";
	position: absolute;
	left: 0;
	top: .65em;
	width: 6px;
	height: 6px;
	border-radius: 50%;
	background: var(--bs-pink);
}

.bs-alert {
	margin: 0 0 14px;
	padding: 10px 14px;
	border-radius: 12px;
	background: #FFF0F4;
	border: 1px solid var(--bs-pink);
	color: var(--bs-pink);
	font-size: 12px;
	font-weight: 700;
}

/* ---------- tabs & chips ---------- */
.bs-tabs { display: flex; gap: 8px; margin-bottom: 14px; }
.bs-tab {
	flex: 1;
	/* Client, 2026-09-14: 「二つのボタンの細さが違うので揃えたい」— the ribbon heading
	   above and this tab render as two stacked pills, so they share one box. */
	padding: 7px 18px; /* 8px minus the 1px border, so it matches .bs-ribbon exactly */
	font: inherit;
	font-size: 15px;
	line-height: 1.5;
	border-radius: 999px;
	border: 1px solid var(--bs-outline);
	background: #fff;
	color: var(--bs-pink);
	cursor: pointer;
}
.bs-tab.is-active { background: var(--bs-pink); border-color: var(--bs-pink); color: #fff; font-weight: 700; }

.bs-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 12px; }
.bs-chip {
	padding: 6px 14px;
	font-size: 12px;
	border-radius: 999px;
	border: 1px solid var(--bs-outline);
	background: #fff;
	color: var(--bs-purple);
	cursor: pointer;
}
.bs-chip.is-active { background: var(--bs-purple); border-color: var(--bs-purple); color: #fff; }

/* ---------- option accordion ---------- */
/*
 * Client, 2026-09-12: replaces a flat stack of every category's full colour
 * grid with one row per category that opens on tap. Collapsed rows are what
 * keep the options step scannable on a phone; only the open one carries a grid.
 */
.bs-accordion {
	margin: 0 0 10px;
	border: 1px solid var(--bs-outline);
	border-radius: 12px;
	background: #fff;
	overflow: hidden;
}
.bs-accordion.is-open { border-color: var(--bs-pink); }
.bs-accordion__head {
	display: flex;
	align-items: center;
	gap: 8px;
	width: 100%;
	padding: 12px 14px;
	background: none;
	border: 0;
	text-align: left;
	font: inherit;
	color: inherit;
	cursor: pointer;
}
.bs-accordion__title { font-size: 13px; font-weight: 700; color: var(--bs-purple); white-space: nowrap; }
.bs-accordion__current {
	flex: 1;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
	font-size: 12px;
	color: #888;
	text-align: right;
}
.bs-accordion__chevron {
	flex: none;
	width: 8px;
	height: 8px;
	border-right: 2px solid var(--bs-pink);
	border-bottom: 2px solid var(--bs-pink);
	transform: rotate(45deg);
	transition: transform .15s ease;
}
.bs-accordion.is-open .bs-accordion__chevron { transform: rotate(-135deg); }
.bs-accordion__body { padding: 0 14px 14px; }

/* ---------- item grid ---------- */
.bs-grid {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: 8px;
}
.bs-item {
	position: relative;
	padding: 6px 4px 8px;
	border: 1px solid var(--bs-outline);
	border-radius: 12px;
	background: #fff;
	text-align: center;
	cursor: pointer;
}
.bs-item.is-selected {
	border-color: var(--bs-pink);
	box-shadow: 0 0 0 2px rgba(236, 79, 129, .25);
}
.bs-item.is-disabled { opacity: .35; pointer-events: none; }
.bs-item img {
	display: block;
	width: 100%;
	aspect-ratio: 1;
	object-fit: contain;
	margin-bottom: 4px;
}
.bs-item span { display: block; font-size: 10px; line-height: 1.4; word-break: break-word; }

/* ---------- sliders ---------- */
.bs-sliders label,
.bs-part-adjust label {
	display: flex;
	align-items: center;
	gap: 10px;
	margin-bottom: 10px;
	font-size: 12px;
}
.bs-sliders input[type="range"],
.bs-part-adjust input[type="range"] {
	flex: 1;
	width: 100%;
	margin: 0;
	accent-color: var(--bs-pink);
}
/*
 * Client, 2026-09-14: 「調整の初期スタート値が分かるように中央に縦線を入れたい」.
 * The wrapper draws a purple tick where the untouched value sits (--bs-tick,
 * 0..1, set by the script from min/max/default). The thumb travels
 * (width - thumb) not the full width, so the tick is offset by half a thumb.
 */
.bs-range {
	position: relative;
	flex: 1;
	display: flex;
	align-items: center;
	min-height: 24px;
}
.bs-range::before {
	content: "";
	position: absolute;
	top: 50%;
	left: calc(8px + var(--bs-tick, .5) * (100% - 16px));
	width: 2px;
	height: 18px;
	transform: translate(-50%, -50%);
	background: var(--bs-purple);
	border-radius: 1px;
	pointer-events: none;
}
.bs-range input[type="range"] { position: relative; }
/*
 * Client, 2026-09-12: 「上下に移動させたりとかもどこにあるのか画面をぱっと見た限り
 * 分かりづらい」 — a thin dashed box in a neutral colour read as part of the
 * background. Solid pink border plus a small heading makes it a distinct,
 * findable control rather than something to notice only by scrolling onto it.
 */
.bs-part-adjust {
	margin-top: 10px;
	padding: 12px;
	border: 1.5px solid var(--bs-pink);
	border-radius: 12px;
	background: #FFF5F8;
}
.bs-part-adjust::before {
	content: "↕ 位置・角度の調整";
	display: block;
	margin-bottom: 8px;
	font-size: 11px;
	font-weight: 700;
	color: var(--bs-pink);
}

/* ---------- upload ---------- */
.bs-upload {
	display: block;
	margin-bottom: 10px;
	padding: 14px;
	text-align: center;
	font-size: 13px;
	color: var(--bs-pink);
	background: #fff;
	border: 1px dashed var(--bs-outline);
	border-radius: 12px;
	cursor: pointer;
}
.bs-upload input { display: none; }
.bs-upload.is-filled { border-style: solid; border-color: var(--bs-pink); }

.bs-cutout { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; }
.bs-cutout__count { font-size: 11px; color: #888; }

/* ---------- buttons ---------- */
.bs-btn {
	display: block;
	width: 100%;
	padding: 14px 12px;
	font-size: 15px;
	font-weight: 700;
	border-radius: 999px;
	border: 1px solid var(--bs-pink);
	cursor: pointer;
}
.bs-btn--primary { background: var(--bs-pink); color: #fff; }
.bs-btn--ghost { background: #fff; color: var(--bs-pink); }
.bs-btn:disabled { opacity: .4; cursor: default; }

/*
 * Client, 2026-09-12: asked whether 戻る/次へ are even needed, to give the
 * option grid above more room (「下部の戻る・次へは必要ないかも」). Removing them
 * outright would take away the only way to move between steps, so instead the
 * bar itself is shrunk (less padding, smaller buttons) rather than dropped.
 */
.bs-nav {
	position: fixed;
	left: 0;
	right: 0;
	bottom: 0;
	display: flex;
	gap: 8px;
	max-width: 520px;
	margin: 0 auto;
	padding: 8px 16px calc(8px + env(safe-area-inset-bottom));
	background: rgba(255, 255, 255, .96);
	border-top: 1px solid var(--bs-outline);
	z-index: 40;
}
.bs-nav .bs-btn { flex: 1; padding: 10px 12px; font-size: 14px; }

/* ---------- summary ---------- */
.bs-summary { margin: 0 0 16px; padding: 0; list-style: none; font-size: 13px; }
.bs-summary li {
	display: flex;
	justify-content: space-between;
	gap: 12px;
	padding: 10px 2px;
	border-bottom: 1px dashed var(--bs-outline);
}
.bs-summary li span:first-child { color: var(--bs-purple); font-weight: 700; }

.bs-note-input { display: block; margin-bottom: 16px; font-size: 12px; }
.bs-note-input textarea {
	width: 100%;
	margin-top: 6px;
	padding: 10px;
	border: 1px solid var(--bs-outline);
	border-radius: 12px;
	font: inherit;
}
.bs-fineprint { margin-top: 10px; font-size: 11px; color: #888; text-align: center; }

/* ---------- loading ---------- */
.bs-loading {
	position: fixed;
	inset: 0;
	display: flex;
	align-items: center;
	justify-content: center;
	background: rgba(255, 255, 255, .8);
	z-index: 100;
}
.bs-loading__box { text-align: center; font-size: 13px; }
.bs-spinner {
	width: 34px;
	height: 34px;
	margin: 0 auto 10px;
	border: 3px solid var(--bs-outline);
	border-top-color: var(--bs-pink);
	border-radius: 50%;
	animation: bs-spin .8s linear infinite;
}
@keyframes bs-spin { to { transform: rotate(360deg); } }

@media (prefers-reduced-motion: reduce) {
	.bs-spinner { animation-duration: 2s; }
}

/* ---------- paid options and the free allowance ---------- */
.bs-badge {
	display: inline-block;
	margin-left: 6px;
	padding: 1px 7px;
	font-size: 10px;
	font-weight: 700;
	line-height: 1.6;
	color: #fff;
	background: var(--bs-purple);
	border-radius: 999px;
	vertical-align: middle;
}
.bs-note--free { margin-bottom: 12px; }
.bs-note--free.is-over { border-color: var(--bs-pink); background: #FFF0F4; font-weight: 700; }

/* ---------- reset ---------- */
.bs-reset { margin: 8px 0 4px; text-align: right; }
.bs-reset__btn {
	padding: 6px 12px;
	font-size: 12px;
	color: #888;
	background: none;
	border: 1px solid var(--bs-outline);
	border-radius: 999px;
	cursor: pointer;
}
.bs-reset__confirm {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
	padding: 12px;
	text-align: left;
	font-size: 12px;
	background: #FFF0F4;
	border: 1px solid var(--bs-pink);
	border-radius: 12px;
}
.bs-reset__confirm span { flex: 1 0 100%; }
.bs-reset__confirm .bs-btn { flex: 1; width: auto; padding: 9px 10px; font-size: 13px; }

.bs-download { margin-bottom: 10px; }

/*
 * Keep the top guidance visible throughout all five steps.  Switching a step
 * must not make the page feel as though its context has vanished; only the
 * preview card becomes sticky while the options are browsed below it.
 */
.bs-app.is-working .bs-steps { margin-top: 4px; }
