@charset "UTF-8";

/*
-------------------------------------------------------

variables

-------------------------------------------------------
*/

:root {
	/* color */
	--color-bg: #08090b;
	--color-text: #eeeef0;
	--color-text-strong: #f5f5f7;
	--color-text-sub: rgba(220, 222, 227, .72);
	--color-text-muted: rgba(220, 222, 227, .66);
	--color-text-faint: rgba(220, 222, 227, .2);
	--color-border: rgba(220, 222, 227, .14);
	--color-divider: rgba(220, 222, 227, .16);
	--color-surface: rgba(220, 222, 227, .09);
	--color-scrollbar: rgba(220, 222, 227, .22);
	--color-header-bg: rgba(8, 9, 11, .72);

	/* 写真の上に重なるボタン。明るい写真でも沈まないよう暗くしておく */
	--color-overlay-button: rgba(8, 9, 11, .55);
	--color-placeholder: rgba(220, 222, 227, .07);

	/* font */
	--font-serif: "Noto Serif JP", "Hiragino Mincho ProN", serif;
	--font-mono: ui-monospace, SFMono-Regular, Menlo, monospace;

	/* font-size（画面幅 375px で最小値、1440px で最大値になるよう調整） */
	--font-size-xs: clamp(11px, 10.65px + .09vw, 12px);
	--font-size-sm: clamp(13px, 12.65px + .09vw, 14px);
	--font-size-base: clamp(14px, 13.3px + .19vw, 16px);
	--font-size-lg: clamp(16px, 14.6px + .38vw, 20px);
	--font-size-xl: clamp(24px, 18.4px + 1.5vw, 40px);

	/* layout */
	--header-height: 80px;
	--side-padding: clamp(16px, 14.6px + .38vw, 20px);
	--grid-gap: 4px;

	/* 指で押す要素の最小サイズ。基準値なので画面幅では変えない */
	--tap-size: 48px;

	/*
		spacing（font-size と同じく 375px〜1440px で変化する）
		両端とも4の倍数。小さい2つは詰まりすぎるので固定値のままにする。
	*/
	--space-2xs: 4px;
	--space-xs: 8px;
	--space-sm: clamp(8px, 6.6px + .38vw, 12px);
	--space-md: clamp(12px, 10.6px + .38vw, 16px);
	--space-lg: clamp(16px, 13.2px + .75vw, 24px);
	--space-xl: clamp(32px, 26.4px + 1.5vw, 48px);

	/* motion */
	--easing: cubic-bezier(.32, .72, .35, 1);
}

/*
-------------------------------------------------------

base

-------------------------------------------------------
*/

* {
	box-sizing: border-box;
}

html,
body {
	margin: 0;
}

body {
	background: var(--color-bg);
	color: var(--color-text);
	font-family: var(--font-serif);
	font-size: var(--font-size-base);

	/*
		文字詰め。

		Google Fonts 版の Noto Serif JP には palt の情報が入っていないため効かない
		（実測でも幅が1pxも変わらなかった）。
		ヒラギノなど端末側のフォントで描画されたときだけ効く。
	*/
	font-feature-settings: "palt";

	-webkit-font-smoothing: antialiased;
}

a {
	color: var(--color-text);
	text-decoration: none;
}

/*
	ホバーはマウスがある環境だけに閉じる。

	タッチ端末では、触れた要素に :hover が残り続けることがある。
	指を離しても薄いまま、という状態を避けるための括り。
*/
@media (hover: hover) {
	a:hover {
		color: rgba(238, 238, 240, .6);
	}
}

button {
	font: inherit;
	color: inherit;
}

h1 {
	margin: 0;
	font-size: inherit;
	font-weight: inherit;
}

p {
	margin: 0;
}

img {
	display: block;
	max-width: 100%;
}

/* Material Symbols。字形名をそのまま書いて、合字でアイコンに変換される */
.icon {
	display: block;
	font-family: "Material Symbols Outlined";
	font-size: 22px;
	line-height: 1;
	font-variation-settings: "FILL" 0, "wght" 200, "GRAD" 0, "opsz" 24;

	/* 合字が効くまでの間、字形名がそのまま出るのを防ぐ */
	font-style: normal;
	letter-spacing: normal;
	text-transform: none;
	white-space: nowrap;
	word-wrap: normal;
	direction: ltr;
	-webkit-font-feature-settings: "liga";
	-webkit-font-smoothing: antialiased;
}

/*
	スクロールバーに幅を指定すると、その分だけ内容の右側が削られてしまう。
	左右を --grid-gap で揃えたいので、OS標準の重ね置き表示に任せる。
	場所を取る形のスクロールバーが使われる環境では、
	.scroller の scrollbar-gutter が左右へ均等に確保する。
*/
::-webkit-scrollbar-thumb {
	background: var(--color-scrollbar);
	border-radius: 10px;
	border: 3px solid transparent;
	background-clip: content-box;
}

/*
-------------------------------------------------------

layout

-------------------------------------------------------
*/

.layout {
	position: relative;
	height: 100vh;
	height: 100dvh;
	overflow: hidden;
	background: var(--color-bg);
}

/* スクロールコンテナ
------------------------------------------------------- */

.scroller {
	position: relative;
	height: 100%;
	padding: var(--header-height) var(--grid-gap) 0;
	overflow-x: hidden;
	overflow-y: auto;

	/* スクロールバーの居場所を左右どちらにも確保して、右だけ余白が増えるのを防ぐ */
	scrollbar-gutter: stable both-edges;

	/* 手動のスクロール位置計算とブラウザの自動補正が競合しないようにする */
	overflow-anchor: none;
}

/*
-------------------------------------------------------

header

-------------------------------------------------------
*/

.header {
	position: absolute;
	top: 0;
	left: 0;
	right: 0;
	z-index: 30;
	background: var(--color-header-bg);
	backdrop-filter: saturate(180%) blur(20px);
	-webkit-backdrop-filter: saturate(180%) blur(20px);
	border-bottom: .5px solid var(--color-border);
}

.header__inner {
	height: var(--header-height);
	padding: 0 var(--side-padding);
	display: flex;
	align-items: center;
	gap: var(--space-md);
}

/* タイトル */
.header__title {
	flex: 1 1 0;
	min-width: 0;
	font-size: var(--font-size-lg);
	font-weight: 500;
	letter-spacing: .02em;
}

/* 押すと列数が初期表示に戻る。見た目は文字のまま */
.header__reset {
	display: block;
	width: 100%;

	/* 行の高さで 48px の当たり判定をつくる（block のままなので省略表示も効く） */
	height: var(--tap-size);
	line-height: var(--tap-size);
	padding: 0;
	border: 0;
	background: transparent;
	font: inherit;
	letter-spacing: inherit;
	text-align: left;
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
	cursor: pointer;
	transition: opacity .2s var(--easing);
}

@media (hover: hover) {
	.header__reset:hover {
		opacity: .6;
	}
}

/* 枚数・列数 */
.header__count {
	font-size: var(--font-size-xs);
	color: var(--color-text-muted);
	white-space: nowrap;
}

/* 狭い画面では枚数・列数を省いて、タイトルを省略せずに見せる */
@media (max-width: 480px) {
	.header__count {
		display: none;
	}
}

/* zoom
------------------------------------------------------- */

.zoom {
	display: flex;
	align-items: center;
	gap: var(--space-2xs);
	background: var(--color-surface);
	border-radius: 8px;
}

/* 指で押す前提なので 48px 四方を確保する（見た目より当たり判定を優先） */
.zoom__button {
	width: var(--tap-size);
	height: var(--tap-size);
	padding: 0;
	border: 0;
	border-radius: 8px;
	background: transparent;
	display: flex;
	align-items: center;
	justify-content: center;
	cursor: pointer;
	transition: opacity .2s var(--easing);
}

.zoom__button:disabled {
	opacity: .32;
	cursor: default;
}

.zoom__divider {
	width: 1px;
	height: 16px;
	background: var(--color-divider);
}

/*
-------------------------------------------------------

intro

-------------------------------------------------------
*/

.intro {
	margin-top: var(--space-xl);
	padding: 0 var(--side-padding);
	text-align: center;
}

/* 2つめ以降の要素だけ間隔をあける */
.intro > * + * {
	margin-top: var(--space-lg);
}

/* en */
.intro__en {
	display: block;
	font-weight: 500;
	font-size: var(--font-size-xl);
	line-height: 1.4;
	letter-spacing: .04em;
	color: var(--color-text-faint);
}

/* かたまりの中では折り返さないので、改行は必ずこの2つの境目で起きる */
.intro__chunk {
	display: inline-block;
	white-space: nowrap;
}

/*
	jp

	keep-all で文中の自動折り返しを止め、wbr を置いた所だけで改行させる。
	それでも収まらないほど狭い場合に限り、anywhere が逃げ道になって溢れを防ぐ。
*/
.intro__lead {
	line-height: 2;
	color: var(--color-text-sub);
	word-break: keep-all;
	overflow-wrap: anywhere;
}

/*
-------------------------------------------------------

grid

-------------------------------------------------------
*/

/* 列数を変えたあと、グリッド全体をひとつの塊として scale で拡縮する（transform は JS が管理する） */
.grid {
	--cols: 5;

	display: grid;
	grid-template-columns: repeat(var(--cols), 1fr);
	gap: var(--grid-gap);
	transform-origin: 50% 50%;
}

/* 年月の見出し。列数がいくつでも1行を占める */
.grid__month {
	grid-column: 1 / -1;
	margin: var(--space-xl) 0 var(--space-lg);
	font-size: var(--font-size-lg);
	font-weight: 500;
	letter-spacing: .08em;
	text-align: center;
	color: var(--color-text-strong);
}

.grid__item {
	position: relative;
	display: block;
	width: 100%;
	padding: 0;
	border: 0;
	aspect-ratio: 1 / 1;
	overflow: hidden;
	background: var(--color-placeholder);
	cursor: pointer;
}

/* 画像は元の縦横比のまま。切り抜きはこの object-fit だけで行う */
.grid__image {
	width: 100%;
	height: 100%;
	object-fit: cover;
	opacity: 0;
	transition: opacity .3s var(--easing);
}

.grid__image.is-loaded {
	opacity: 1;
}

/* キーボードで辿っているときは、端末を問わず示す */
.grid__item:focus-visible .grid__image.is-loaded {
	opacity: .55;
}

/* ホバー中は下の色が透けて、選んでいる1枚が分かる */
@media (hover: hover) {
	.grid__item:hover .grid__image.is-loaded {
		opacity: .55;
	}
}

/* 読み込み状況
------------------------------------------------------- */

.status {
	margin-top: var(--space-xl);
	padding: 0 var(--side-padding);
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var(--space-sm);
	text-align: center;
	font-size: var(--font-size-xs);
	letter-spacing: .06em;
	color: var(--color-text-muted);
	min-height: 1em;
}

/* 読み込み中だけ回す */
.status__spinner {
	display: none;
	width: 20px;
	height: 20px;
	border: 2px solid var(--color-divider);
	border-top-color: var(--color-text-sub);
	border-radius: 50%;
	animation: spin .8s linear infinite;
}

.status.is-loading .status__spinner {
	display: block;
}

@keyframes spin {
	to {
		transform: rotate(360deg);
	}
}

/*
-------------------------------------------------------

closing / footer

-------------------------------------------------------
*/

.closing {
	margin-top: var(--space-xl);
	padding: 0 var(--side-padding);
	text-align: center;
	line-height: 2;
	color: var(--color-text-sub);
}

/*
	周りの文より明るくして、リンクだと分かるようにする。
	inline への縦paddingは行の高さに影響しないので、
	見た目を変えずに当たり判定だけ広げられる。
*/
.closing__link {
	padding: var(--space-xs) 2px;
	color: var(--color-text-strong);
	transition: opacity .2s var(--easing);
}

@media (hover: hover) {
	.closing__link:hover {
		color: var(--color-text-strong);
		opacity: .6;
	}
}

.footer {
	margin-top: var(--space-xl);
	padding: var(--space-lg) var(--side-padding) var(--space-xl);
	border-top: .5px solid var(--color-border);
	text-align: center;
}

/* copyright */
.footer__copyright {
	font-size: var(--font-size-xs);
	letter-spacing: .08em;
	color: var(--color-text-muted);
}

/*
-------------------------------------------------------

viewer

-------------------------------------------------------
*/

/* サムネイルの位置から等倍の位置へ、transform で飛ばす（transform と clip-path は JS が管理する） */
.viewer {
	position: absolute;
	inset: 0;
	z-index: 40;
	display: flex;
	align-items: center;
	justify-content: center;
	cursor: pointer;

	/* 送り・下引き・ピンチをすべて自前で扱うので、ブラウザ側の解釈を止める */
	touch-action: none;

	/* 掴んで動かすので、文字選択や画像のドラッグが割り込まないようにする */
	user-select: none;
	-webkit-user-select: none;
}

.viewer[hidden] {
	display: none;
}

.viewer__scrim {
	position: absolute;
	inset: 0;
	background: var(--color-bg);
}

/*
	前・現在・次の3枚を横に並べておき、この track ごと動かす。
	transform は JS が管理する（指の動きに追従させるため）。
*/
.viewer__track {
	position: absolute;
	inset: 0;

	/* 横は自前で処理するので、ブラウザ側の横スクロール解釈を止める */
	touch-action: pan-y;
}

.viewer__slide {
	position: absolute;
	inset: 0;
	display: flex;
	align-items: center;
	justify-content: center;
}

.viewer__slide[hidden] {
	display: none;
}

/* 両隣は画面の外に控えさせる。写真同士がくっつかないよう1枚ぶんより離す */
.viewer__slide--prev {
	transform: translateX(calc(-100% - var(--side-padding)));
}

.viewer__slide--next {
	transform: translateX(calc(100% + var(--side-padding)));
}

/*
	写真の縦横比のまま画面に収める。クリップしないので全体が見える。
	--ratio は開いた写真に合わせて JS が入れる（既定値は多数派の縦長 3:4）
*/
.viewer__photo {
	--ratio: .75;

	position: relative;
	width: min(100vw, calc(100dvh * var(--ratio)));
	aspect-ratio: var(--ratio);
}

.viewer__image {
	width: 100%;
	height: 100%;
	object-fit: contain;

	/* ブラウザ標準の画像ドラッグが、送りの操作を邪魔しないようにする */
	-webkit-user-drag: none;
	pointer-events: none;
}

/* 送っている間は日付だけ薄くして、着地してから新しい日付を出す */
.viewer__caption {
	transition: opacity .16s var(--easing);
}

.viewer.is-sliding .viewer__caption {
	opacity: 0;
}

.viewer__caption {
	position: absolute;
	left: 0;
	right: 0;
	bottom: var(--side-padding);
	text-align: center;
	font-family: var(--font-mono);
	font-size: var(--font-size-xs);
	letter-spacing: .08em;
	color: var(--color-text-strong);

	/* 明るい写真に重なっても読めるように、文字の背後だけ暗く落とす */
	text-shadow: 0 0 8px rgba(8, 9, 11, .9), 0 0 2px rgba(8, 9, 11, .9);
	pointer-events: none;
}

.viewer__close {
	position: absolute;
	top: var(--space-sm);
	right: var(--space-sm);
	width: var(--tap-size);
	height: var(--tap-size);
	padding: 0;
	border: 0;
	border-radius: 8px;
	background: var(--color-overlay-button);
	backdrop-filter: blur(8px);
	-webkit-backdrop-filter: blur(8px);
	color: var(--color-text-strong);
	display: flex;
	align-items: center;
	justify-content: center;
	cursor: pointer;
}

/* 前後の写真へ
------------------------------------------------------- */

.viewer__nav {
	position: absolute;
	top: 50%;
	width: var(--tap-size);
	height: var(--tap-size);
	margin-top: calc(var(--tap-size) / -2);
	padding: 0;
	border: 0;
	border-radius: 50%;
	background: var(--color-overlay-button);
	backdrop-filter: blur(8px);
	-webkit-backdrop-filter: blur(8px);
	color: var(--color-text-strong);
	display: flex;
	align-items: center;
	justify-content: center;
	cursor: pointer;
	transition: opacity .2s var(--easing);
}

/* 狭い画面では写真を隠さないよう、矢印を出さずスワイプで送る */
@media (max-width: 480px) {
	.viewer__nav {
		display: none;
	}
}

.viewer__nav:disabled {
	opacity: .24;
	cursor: default;
}

.viewer__nav--prev {
	left: var(--space-sm);
}

/* 前へは同じ矢印を反転して使う */
.viewer__nav--prev .icon {
	transform: rotate(180deg);
}

.viewer__nav--next {
	right: var(--space-sm);
}
