/* 1440 — Inter (Latin) + Pretendard (Hangul), Geist Mono for numbers.
   Plain type, kept quiet: paper, ink, hairlines and a grain you barely see. Things arrive slowly out of a blur and say little until they are asked. */

:root {
  --bg: #f8f8f6;
  --ink: rgba(8, 8, 8, 0.9);
  --ink-2: rgba(8, 8, 8, 0.58);
  --ink-3: rgba(8, 8, 8, 0.34);
  --ink-4: rgba(8, 8, 8, 0.1);
  --accent: #0a5cff;
  --veil: color-mix(in srgb, var(--bg) 78%, transparent);
  --slow: cubic-bezier(.2, .7, .2, 1);

  --sans: "Inter", "Pretendard Variable", "Pretendard", system-ui, sans-serif;
  --mono: "Geist Mono", ui-monospace, "SFMono-Regular", monospace;

  --fs-xl: clamp(32px, 7.2vw, 104px);
  --gutter: clamp(16px, 1.6vw, 24px);
  --bar-h: clamp(44px, 1.2vw + 38px, 56px);
  --fs-body: clamp(13px, 0.22vw + 12.2px, 15px);
  --fs-small: clamp(11px, 0.14vw + 10.5px, 12.5px);
}

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; height: 100%; }

body {
  margin: 0;
  min-height: 100%;
  display: flex;
  flex-direction: column;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--sans);
  font-size: var(--fs-body);
  line-height: 1.6;
  letter-spacing: -0.005em;
  word-break: keep-all;
  -webkit-font-smoothing: antialiased;
}

/* behind everything: a fine grain */
body::after {
  content: ""; position: fixed; inset: 0; z-index: -1; pointer-events: none;
  opacity: 0.075;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 .5 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

a { color: inherit; text-decoration: none; }
:focus-visible { outline: 1px solid var(--ink); outline-offset: 3px; }
::selection { background: #0b0b0b; color: #f8f8f6; }
html { scrollbar-width: thin; scrollbar-color: var(--ink-4) transparent; }


/* header: 1440 on the left, menu on the right */
.bar {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  height: var(--bar-h);
  padding-inline: var(--gutter);
  /* header type scales with the screen: 12px on phones up to 13.5px on wide screens */
  font-size: clamp(12px, 0.18vw + 11.2px, 13.5px);
}
/* "1440" — pointed at, the letters melt away and the tab icon (a circle) takes their place */
.bar .home { justify-self: start; display: inline-grid; align-items: center; justify-items: center; font-weight: 500; letter-spacing: -0.02em; font-variant-numeric: tabular-nums; }
.bar .home > span { grid-area: 1 / 1; transition: opacity .8s ease, filter .9s var(--slow); }
.bar .home .mid { display: grid; place-items: center; opacity: 0; filter: blur(5px); }
.bar .home .mid svg { width: 1.6em; height: 1.6em; }
@media (hover: hover) {
  .bar .home:hover .t, .bar .home:focus-visible .t { opacity: 0; filter: blur(5px); }
  .bar .home:hover .mid, .bar .home:focus-visible .mid { opacity: 1; filter: none; }
}
.bar .menu { grid-column: 3; justify-self: end; display: flex; gap: 1.4em; }
.bar .menu a { color: var(--ink-3); transition: color .4s; }
.bar .menu a:hover, .bar .menu a[aria-current="page"] { color: var(--ink); }

/* first screen */
.hero {
  flex: 1;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  align-content: center;
  gap: clamp(16px, 2vw, 32px) var(--gutter);
  padding: 8vh calc(clamp(8px, 1.5vw, 28px) + clamp(10px, 0.55vw + 7px, 15px) + 14px) 12vh var(--gutter);
}

.lines { min-width: 0; }

.hero h1,
.claim,
.tagline {
  margin: 0;
  font-size: var(--fs-xl);
  font-weight: 400;
  line-height: 1.08;
  letter-spacing: -0.05em;
}

/* ---------- first-visit intro ----------
   1. "나만의 졸업전시" types itself on a blank page
   2. "내가 원하는 주소로." shows for two seconds in the address line's place
   3. the address line, header, clock and footer fade in */
.typed { display: none; }
.typed::after {
  content: "";
  display: inline-block;
  width: 0.05em;
  height: 0.82em;
  margin-left: 0.04em;
  vertical-align: -0.06em;
  background: currentColor;
  animation: blink 1s steps(1) infinite;
}
html.intro-typing .typed { display: inline; }
html.intro-typing .real { display: none; }

.line2 { display: grid; }
.line2 > .tagline,
.line2 > .claim { grid-area: 1 / 1; }
.tagline {
  opacity: 0;
  filter: blur(10px);
  pointer-events: none;
  transition: opacity .9s ease, filter 1.1s var(--slow);
}
.line2.show-tagline .tagline { opacity: 1; filter: none; }

.claim, .bar, .biz, .minute { transition: opacity 1.2s ease, filter 1.4s var(--slow); }
html.intro .claim,
html.intro .bar,
html.intro .biz,
html.intro .minute { opacity: 0; visibility: hidden; filter: blur(8px); }

/* rotating word after 나만의 */
.rot {
  display: inline-grid;
  vertical-align: bottom;
}
.rot .w {
  grid-area: 1 / 1;
  white-space: nowrap;
  opacity: 0;
  filter: blur(14px);
  transition: opacity 1.1s ease, filter 1.3s var(--slow);
}
.rot .w.is-on { opacity: 1; filter: none; transition-delay: .35s; }
.rot .w.is-out { opacity: 0; filter: blur(14px); transition-duration: .8s, 1s; }

/* examples always fit on one line (JS sizes the type for the longest one);
   a longer name typed by the visitor pushes ".kor.gallery →" to the next line */
.claim {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  column-gap: 0;
}

/* the typed / editable name, sized to its content */
.name {
  position: relative;
  display: inline-grid;
  grid-template-columns: minmax(0, max-content);
  align-items: baseline;
  flex: 0 1 auto;
  min-width: 0;
  max-width: 100%;
  cursor: text;
}
.name .sizer,
.name input {
  grid-area: 1 / 1;
  font: inherit;
  letter-spacing: inherit;
  white-space: pre;
}
.name .sizer { visibility: hidden; padding-right: 0.02em; }
.name input {
  width: 100%;
  min-width: 0;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--ink);
  caret-color: var(--accent);
  outline: none;
  border-bottom: 0.045em solid var(--ink-4);
  transition: border-color .2s;
}
.name input::placeholder { color: var(--ink-3); opacity: 1; }
.name input:focus { border-bottom-color: var(--accent); }
.claim.invite .name input { animation: invite 1.2s ease-out 1; }
@keyframes invite {
  0% { border-bottom-color: var(--ink-4); }
  25% { border-bottom-color: var(--accent); box-shadow: 0 0.06em 0 0 color-mix(in srgb, var(--accent) 35%, transparent); }
  100% { border-bottom-color: var(--accent); box-shadow: none; }
}
.name:focus-within { outline: none; }

/* blinking caret shown while the example names type themselves */
.name .caret {
  position: absolute;
  right: -0.04em;
  top: 0.14em;
  width: 0.05em;
  height: 0.84em;
  background: var(--ink-3);
  animation: blink 1s steps(1) infinite;
}
.claim.editing .caret { display: none; }

/* the visitor's own name fills right to left from ".kor.gallery":
   the box starts three characters wide and grows as the name gets longer */
.name { min-width: 3ch; }
.claim.editing .name { grid-template-columns: minmax(0, 1fr); }
.claim.editing .name input { text-align: right; }
@keyframes blink { 50% { opacity: 0; } }

.tld { white-space: nowrap; display: inline-flex; align-items: center; }

/* → in a circle. The ring is as tall as a capital letter and drawn with the same
   stroke weight as the type, so it reads as part of the line rather than a widget */
.go {
  display: inline-grid;
  place-items: center;
  flex: 0 0 auto;
  font: inherit;
  /* centred on the letter "y" of ".gallery": Inter's y runs from x-height (0.55em above
     the baseline) to its descender (0.21em below), so its middle is 0.17em above the
     baseline. The flex line centres the ring 0.365em above the baseline; move it down
     the difference. The ring (0.74em) then spans the y from top to tail. */
  position: relative;
  top: 0.195em;
  width: 0.74em;
  height: 0.74em;
  margin-left: 0.2em;
  padding: 0;
  border: max(1.5px, 0.055em) solid currentColor;
  border-radius: 50%;
  background: transparent;
  color: var(--ink-3);
  cursor: pointer;
  transition: color .25s, background-color .25s, border-color .25s, transform .15s;
}
.go svg {
  width: 0.4em;
  height: 0.4em;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.7;
  stroke-linecap: round;
  stroke-linejoin: round;
  transition: transform .25s cubic-bezier(.2, .7, .2, 1);
}
.claim.ready .go { color: var(--ink); }
.go:hover { background: var(--ink); border-color: var(--ink); color: var(--bg); }
.go:hover svg { transform: translateX(0.04em); }
.go:active { transform: scale(0.96); }

/* the visitor has finished typing a valid name: the → blinks to say "press me" */
.claim.nudge .go { animation: nudge 1.1s ease-in-out infinite; }
@keyframes nudge {
  0%, 100% { background: transparent; color: var(--ink); border-color: var(--ink); }
  50% { background: var(--ink); color: var(--bg); border-color: var(--ink); }
}
@media (prefers-reduced-motion: reduce) {
  .claim.nudge .go { background: var(--ink); color: var(--bg); border-color: var(--ink); }
}

.status {
  margin: clamp(12px, 1.4vw, 22px) 0 0;
  min-height: 1.6em;
  font-size: var(--fs-body);
  color: var(--ink-2);
}

/* minute of the day: vertical, grey, pinned at the right edge, halfway down the screen.
   Size, offset and spacing follow the screen so it stays in proportion everywhere */
.minute {
  position: fixed;
  top: 50%;
  transform: translateY(-50%);
  right: clamp(8px, 1.5vw, 28px);
  writing-mode: vertical-rl;
  font-family: var(--mono);
  font-size: clamp(10px, 0.55vw + 7px, 15px);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.08em;
  color: var(--ink-3);
  white-space: nowrap;
  animation: breathe 7s ease-in-out infinite;
}
@keyframes breathe { 50% { color: var(--ink-4); } }
html.intro .minute { animation: none; }

/* business information */
.biz {
  padding: clamp(14px, 1.2vw, 22px) var(--gutter) max(clamp(16px, 1.4vw, 26px), env(safe-area-inset-bottom, 0px));
  font-size: clamp(10.5px, 0.1vw + 10.2px, 11.5px);
  color: var(--ink-2);
  letter-spacing: 0;
}
.biz dl { margin: 0; display: flex; flex-wrap: wrap; gap: 0.25em 2em; }
.biz dl div { display: flex; gap: 0.7em; }
.biz dt { color: var(--ink-3); }
.biz dd { margin: 0; min-width: 0; font-variant-numeric: tabular-nums; }
.biz dt { flex: 0 0 auto; }
.biz a { color: inherit; text-decoration: underline; text-decoration-color: var(--ink-4); text-underline-offset: 0.2em; }
@media (hover: hover) { .biz a:hover { color: var(--ink); text-decoration-color: currentColor; } }

@media (max-width: 700px) {
  .biz dl { flex-direction: column; }
}

/* ---------- 정보: comes up over the first page, laid out as a quiet two-column information page ----------
   The screen is cut in two. The left half stays empty (the page shows through a veil). The right half holds a grey
   list on its left (the chosen one dark) and the text on its right. One size of type; the only ranking is how dark
   it is. Sections are told apart by hairlines, and the page title sits a little inside the column. */
.page-home .bar { position: relative; z-index: 50; }
.page-home .minute { z-index: 45; }
.bar .menu a[aria-expanded="true"] { color: var(--ink); }
.info-ov {
  --t: clamp(12.5px, 0.22vw + 11.4px, 14.5px);
  position: fixed; inset: var(--bar-h) 0 0 0; z-index: 40;
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); align-content: start;
  overflow-y: auto;
  font-size: var(--t);
  background: transparent; /* nothing behind the words: only the words */
  opacity: 0; visibility: hidden; pointer-events: none;
  transition: opacity .9s ease, visibility 0s linear .9s;
}
.info-ov::before { content: ""; position: fixed; top: var(--bar-h); left: 50%; right: 0; border-top: 1px solid var(--ink-4); }
.info-side { position: sticky; top: 1.05em; }
.info-ov.open { opacity: 1; visibility: visible; pointer-events: auto; transition: opacity .9s ease, visibility 0s; }
.info-half { grid-column: 2; display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 2fr); padding: 1.05em calc(clamp(8px, 1.5vw, 28px) + clamp(10px, 0.55vw + 7px, 15px) + 14px) clamp(48px, 9vh, 120px) 0; }
.info-ov .info-half > * { filter: blur(8px); opacity: 0; transition: opacity 1.1s ease .15s, filter 1.3s var(--slow) .15s; }
.info-ov.open .info-half > * { filter: none; opacity: 1; }
.info-side { display: flex; flex-direction: column; align-items: flex-start; line-height: 1.18; align-self: start; }
.info-side a { color: var(--ink-3); transition: color .5s; }
.info-side a.on { color: var(--ink); }
@media (hover: hover) { .info-side a:hover { color: var(--ink); } }
.info-side .gap { height: 1.3em; }

.info-body { min-width: 0; }
.info-page { display: none; }
.info-page.on { display: grid; gap: 1.3em; align-content: start; animation: riseIn 1.1s var(--slow) both; }
@keyframes riseIn { from { opacity: 0; filter: blur(10px); } }
.info-page p, .info-page li, .info-page h2 { margin: 0; font-size: 1em; font-weight: 400; line-height: 1.32; letter-spacing: -0.005em; color: var(--ink); }
.info-page .dim { color: var(--ink-3); }
.info-page a { transition: color .5s; }
@media (hover: hover) { .info-page a:hover { color: var(--ink-3); } }
.info-title { padding-left: 2.4em; }
.sq, .no { margin: 0; padding: 0; list-style: none; display: grid; gap: 0.15em; }
.sq li { display: grid; grid-template-columns: 1.3em 1fr; }
.sq li::before { content: ""; width: 0.42em; height: 0.42em; margin-top: 0.5em; background: currentColor; }
.no li { display: grid; grid-template-columns: 2.4em 1fr; gap: 0; padding: 0.35em 0; }
.no li > span:first-child { font-family: var(--mono); font-size: 0.92em; color: var(--ink-3); padding-top: 0.05em; }
.two { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1.3em 1.6em; border-top: 1px solid var(--ink-4); padding-top: 1.2em; margin-top: 0.6em; }
.two section { display: grid; gap: 1em; align-content: start; }
.two h2 { padding-left: 2.4em; }
/* a price list: a small empty box, the name, the price at the end (a list of billing choices) */
.ck { margin: 0; padding: 0; list-style: none; display: grid; gap: 0.35em; }
.ck li { display: grid; grid-template-columns: 1.3em 1fr auto; align-items: baseline; gap: 0 0.4em; }
.ck .b { width: 0.72em; height: 0.72em; border: 1px solid currentColor; align-self: center; }
.ck em { font-style: normal; color: var(--ink-3); margin-left: 0.5em; }
.ck .v { text-align: right; }
/* documents: articles set one under the other, each with its short title */
.doc { gap: 1.1em; }
.doc section { display: grid; gap: 0.4em; align-content: start; }
.doc h2 { color: var(--ink); }
.doc section p, .doc section li { color: var(--ink-2); }
.doc section .sq { margin-top: 0.1em; }
@media (max-width: 760px) {
  .info-ov::before { display: none; }
  .info-side { position: static; }
  /* one column: the words would sit right on top of the first page, so here (only here) a paper veil goes behind them */
  .info-ov { display: block; background: color-mix(in srgb, var(--bg) 94%, transparent); backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px); }
  .info-half { display: block; padding: 1.4em calc(clamp(8px, 1.5vw, 28px) + clamp(10px, 0.55vw + 7px, 15px) + 14px) 3em var(--gutter); }
  .info-side { flex-direction: row; flex-wrap: wrap; gap: 0.2em 1.2em; margin-bottom: 1.8em; }
  .info-side .gap { display: none; }
  .info-title { padding-left: 0; }
  .two h2 { padding-left: 0; }
  .two { grid-template-columns: minmax(0, 1fr); }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
}

/* ---------- 계정: Login beside Information; the nickname with My hub under it; the account layer ----------
   The layer is the Information layer again (words only, out of a blur). Fields are a hairline to write on,
   the one button a thin round outline, and every message one line of grey (red only for a mistake). */
.bar .menu .acct { position: relative; display: inline-block; }
.bar .menu .acct .nick { display: inline-block; max-width: 10em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; vertical-align: bottom; color: var(--ink); }
.bar .menu .acct .hub { position: absolute; right: 0; top: 100%; padding-top: 0.45em; white-space: nowrap; color: var(--ink); opacity: 0; filter: blur(5px); pointer-events: none; transition: opacity .7s ease, filter .9s var(--slow); }
.bar .menu .acct .hub::before { content: ""; display: inline-block; width: 0.42em; height: 0.42em; margin-right: 0.45em; vertical-align: 0.12em; background: currentColor; }
@media (hover: hover) { .bar .menu .acct:hover .hub { opacity: 1; filter: none; pointer-events: auto; } }
.bar .menu .acct:focus-within .hub, .bar .menu .acct.peek .hub { opacity: 1; filter: none; pointer-events: auto; }
.acct-ov .info-side .m, .acct-ov .info-side .a, .acct-ov.in .info-side .g { display: none; }
.acct-ov.in .info-side .m, .acct-ov.is-admin .info-side .a { display: inline; }
.acct-f { display: grid; gap: 1.05em; max-width: 26em; }
.acct-f[hidden], .acct-ov [hidden] { display: none; }
.fld { display: grid; gap: 0.2em; }
.fld > span { color: var(--ink-3); }
.fld em, .ckx em { font-style: normal; color: var(--ink-3); margin-left: 0.4em; }
.fld input { font: inherit; color: var(--ink); background: transparent; border: 0; border-bottom: 1px solid var(--ink-4); border-radius: 0; padding: 0.3em 0; outline: 0; transition: border-color .6s; -webkit-appearance: none; appearance: none; }
.fld input:focus { border-bottom-color: var(--ink); }
.ckx { display: grid; grid-template-columns: 1.3em minmax(0, 1fr); align-items: start; cursor: pointer; }
.ckx input { -webkit-appearance: none; appearance: none; width: 0.72em; height: 0.72em; margin: 0.42em 0 0; border: 1px solid var(--ink); border-radius: 0; background: transparent; cursor: pointer; }
.ckx input:checked { background: var(--ink); }
.acct-go { justify-self: start; font: inherit; color: var(--ink); background: transparent; border: 1px solid var(--ink); border-radius: 99px; padding: 0.3em 1.1em; cursor: pointer; transition: background .5s, color .5s; }
@media (hover: hover) { .acct-go:not([disabled]):hover { background: var(--ink); color: var(--bg); } }
.acct-go[disabled] { opacity: 0.35; cursor: default; }
.acct-msg { margin: 0; min-height: 1.32em; color: var(--ink-2); }
.acct-msg.err { color: #b8231a; }
.acct-ov .u { text-decoration: underline; text-decoration-color: var(--ink-4); text-underline-offset: 0.2em; transition: text-decoration-color .5s, color .5s; font: inherit; color: inherit; background: none; border: 0; padding: 0; cursor: pointer; }
@media (hover: hover) { .acct-ov .u:hover { text-decoration-color: currentColor; } }
.acct-local { margin-top: 2.6em; max-width: 30em; }
.acct-dl .v { text-align: right; min-width: 0; overflow-wrap: anywhere; }
.adm { display: grid; gap: 0.5em; border-top: 1px solid var(--ink-4); padding-top: 1em; }
.adm-q { max-width: 18em; }
.adm-r { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 0.3em 1.2em; padding: 0.55em 0; border-bottom: 1px solid var(--ink-4); align-items: start; }
.adm-r em { font-style: normal; color: var(--ink-3); }
.adm-r.dim { color: var(--ink-3); }
.adm-b { display: flex; gap: 1em; white-space: nowrap; }
@media (max-width: 760px) {
  .bar .menu .acct .nick { max-width: 6.5em; }
  .acct-f { max-width: none; }
}
.acct-ov .pay { display: grid; gap: 0.6em; border-top: 1px solid var(--ink-4); padding-top: 1.1em; margin-top: 0.6em; }
.acct-ov .pay .ck .v { text-align: right; }
.acct-ov .pay button[disabled] { opacity: .35; cursor: default; }
