site.css 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430
  1. /* ==========================================================================
  2. Dark, minimal photography theme — shared by public site and admin.
  3. ========================================================================== */
  4. :root {
  5. --bg: #0b0b0c;
  6. --bg-raise: #151517;
  7. --fg: #f4f4f2;
  8. --muted: #9a9a96;
  9. --line: #29292c;
  10. --danger: #e05b4d;
  11. --ok: #6fbf8f;
  12. --nav-h: 64px;
  13. }
  14. * { box-sizing: border-box; margin: 0; padding: 0; }
  15. html { scroll-behavior: smooth; }
  16. body {
  17. background: var(--bg);
  18. color: var(--fg);
  19. font-family: "Helvetica Neue", Helvetica, Arial, system-ui, sans-serif;
  20. font-size: 16px;
  21. line-height: 1.6;
  22. -webkit-font-smoothing: antialiased;
  23. }
  24. img { max-width: 100%; display: block; }
  25. a { color: inherit; text-decoration: none; }
  26. /* --------------------------------------------------------------------------
  27. Public navigation — fixed, hides on scroll-down, returns on scroll-up
  28. -------------------------------------------------------------------------- */
  29. .nav {
  30. position: fixed;
  31. inset: 0 0 auto 0;
  32. height: var(--nav-h);
  33. display: flex;
  34. align-items: center;
  35. justify-content: space-between;
  36. padding: 0 clamp(1.25rem, 4vw, 3rem);
  37. z-index: 100;
  38. background: linear-gradient(to bottom, rgba(0,0,0,.55), rgba(0,0,0,0));
  39. transition: transform .35s ease, opacity .35s ease;
  40. }
  41. .nav.nav-hidden {
  42. transform: translateY(-100%);
  43. opacity: 0;
  44. pointer-events: none;
  45. }
  46. .nav-brand {
  47. font-size: 1.05rem;
  48. letter-spacing: .18em;
  49. text-transform: uppercase;
  50. font-weight: 500;
  51. }
  52. .nav-links {
  53. display: flex;
  54. gap: 2rem;
  55. }
  56. .nav-links a {
  57. font-size: .8rem;
  58. letter-spacing: .22em;
  59. text-transform: uppercase;
  60. color: var(--muted);
  61. transition: color .2s;
  62. }
  63. .nav-links a:hover, .nav-links a.active { color: var(--fg); }
  64. /* --------------------------------------------------------------------------
  65. Landing page
  66. -------------------------------------------------------------------------- */
  67. .hero {
  68. position: relative;
  69. height: 100svh;
  70. overflow: hidden;
  71. }
  72. .hero img {
  73. width: 100%;
  74. height: 100%;
  75. object-fit: cover;
  76. }
  77. .hero-placeholder {
  78. width: 100%;
  79. height: 100%;
  80. background: radial-gradient(120% 90% at 50% 20%, #1d1d21 0%, #0b0b0c 70%);
  81. }
  82. .hero-caption {
  83. position: absolute;
  84. inset: auto 0 0 0;
  85. padding: clamp(2rem, 8vh, 6rem) clamp(1.25rem, 4vw, 3rem);
  86. background: linear-gradient(to top, rgba(0,0,0,.65), rgba(0,0,0,0));
  87. }
  88. .hero-caption h1 {
  89. font-size: clamp(2.2rem, 6vw, 4.5rem);
  90. font-weight: 300;
  91. letter-spacing: .12em;
  92. text-transform: uppercase;
  93. }
  94. .hero-scroll-hint {
  95. position: absolute;
  96. bottom: 1.2rem;
  97. left: 50%;
  98. translate: -50% 0;
  99. color: rgba(255,255,255,.7);
  100. font-size: 1.4rem;
  101. animation: hint 2.2s ease-in-out infinite;
  102. }
  103. @keyframes hint {
  104. 0%, 100% { transform: translateY(0); opacity: .5; }
  105. 50% { transform: translateY(8px); opacity: 1; }
  106. }
  107. .intro {
  108. max-width: 42rem;
  109. margin: 0 auto;
  110. padding: clamp(4rem, 14vh, 9rem) 1.5rem;
  111. text-align: center;
  112. }
  113. .intro p {
  114. font-size: clamp(1.05rem, 1.6vw, 1.3rem);
  115. font-weight: 300;
  116. color: var(--fg);
  117. white-space: pre-line;
  118. line-height: 1.9;
  119. }
  120. .intro .cta {
  121. display: inline-block;
  122. margin-top: 3rem;
  123. padding: .9rem 2.6rem;
  124. border: 1px solid var(--fg);
  125. font-size: .8rem;
  126. letter-spacing: .25em;
  127. text-transform: uppercase;
  128. transition: background .25s, color .25s;
  129. }
  130. .intro .cta:hover { background: var(--fg); color: var(--bg); }
  131. /* --------------------------------------------------------------------------
  132. Showreel — one image per viewport, scroll snap
  133. -------------------------------------------------------------------------- */
  134. body.reel-page { scroll-snap-type: y mandatory; }
  135. .reel-slide {
  136. height: 100svh;
  137. scroll-snap-align: start;
  138. scroll-snap-stop: always;
  139. display: flex;
  140. align-items: center;
  141. justify-content: center;
  142. background: #000;
  143. }
  144. .reel-slide img {
  145. max-width: 100%;
  146. max-height: 100svh;
  147. width: auto;
  148. height: auto;
  149. object-fit: contain;
  150. }
  151. .reel-empty {
  152. height: 100svh;
  153. display: grid;
  154. place-items: center;
  155. color: var(--muted);
  156. letter-spacing: .1em;
  157. }
  158. /* --------------------------------------------------------------------------
  159. Gallery — password gate, thumbnail grid, lightbox
  160. -------------------------------------------------------------------------- */
  161. .page {
  162. max-width: 1400px;
  163. margin: 0 auto;
  164. padding: calc(var(--nav-h) + 3rem) clamp(1rem, 3vw, 2.5rem) 4rem;
  165. }
  166. .page-title {
  167. font-weight: 300;
  168. letter-spacing: .1em;
  169. text-transform: uppercase;
  170. font-size: clamp(1.4rem, 3vw, 2.2rem);
  171. margin-bottom: .4rem;
  172. }
  173. .page-sub { color: var(--muted); font-size: .9rem; margin-bottom: 2.5rem; }
  174. .gate {
  175. min-height: 100svh;
  176. display: grid;
  177. place-items: center;
  178. padding: 1.5rem;
  179. }
  180. .gate-card {
  181. width: 100%;
  182. max-width: 24rem;
  183. text-align: center;
  184. }
  185. .gate-card h1 {
  186. font-weight: 300;
  187. letter-spacing: .12em;
  188. text-transform: uppercase;
  189. font-size: 1.4rem;
  190. margin-bottom: 1.8rem;
  191. }
  192. .grid {
  193. display: grid;
  194. grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  195. gap: 6px;
  196. }
  197. .grid a {
  198. position: relative;
  199. aspect-ratio: 3 / 2;
  200. overflow: hidden;
  201. background: var(--bg-raise);
  202. }
  203. .grid img {
  204. width: 100%;
  205. height: 100%;
  206. object-fit: cover;
  207. transition: transform .4s ease, opacity .4s;
  208. opacity: .92;
  209. }
  210. .grid a:hover img { transform: scale(1.03); opacity: 1; }
  211. /* Lightbox */
  212. .lightbox {
  213. position: fixed;
  214. inset: 0;
  215. z-index: 200;
  216. background: rgba(0,0,0,.96);
  217. display: none;
  218. align-items: center;
  219. justify-content: center;
  220. }
  221. .lightbox.open { display: flex; }
  222. .lightbox img {
  223. max-width: 96vw;
  224. max-height: 96svh;
  225. object-fit: contain;
  226. }
  227. .lightbox button {
  228. position: absolute;
  229. background: none;
  230. border: none;
  231. color: rgba(255,255,255,.75);
  232. font-size: 2rem;
  233. cursor: pointer;
  234. padding: 1rem;
  235. line-height: 1;
  236. transition: color .2s;
  237. }
  238. .lightbox button:hover { color: #fff; }
  239. .lb-close { top: .5rem; right: .8rem; }
  240. .lb-prev { left: .4rem; top: 50%; translate: 0 -50%; }
  241. .lb-next { right: .4rem; top: 50%; translate: 0 -50%; }
  242. .lb-count {
  243. position: absolute;
  244. bottom: 1rem;
  245. left: 50%;
  246. translate: -50% 0;
  247. color: var(--muted);
  248. font-size: .8rem;
  249. letter-spacing: .15em;
  250. }
  251. /* --------------------------------------------------------------------------
  252. Footer
  253. -------------------------------------------------------------------------- */
  254. .footer {
  255. padding: 2.5rem clamp(1.25rem, 4vw, 3rem);
  256. color: var(--muted);
  257. font-size: .75rem;
  258. letter-spacing: .15em;
  259. text-transform: uppercase;
  260. text-align: center;
  261. }
  262. /* --------------------------------------------------------------------------
  263. Forms (shared)
  264. -------------------------------------------------------------------------- */
  265. label { display: block; font-size: .8rem; letter-spacing: .12em; text-transform: uppercase; color: var(--muted); margin: 1.1rem 0 .35rem; }
  266. input[type=text], input[type=password], input[type=date], textarea, select {
  267. width: 100%;
  268. padding: .7rem .9rem;
  269. background: var(--bg-raise);
  270. border: 1px solid var(--line);
  271. color: var(--fg);
  272. font: inherit;
  273. border-radius: 4px;
  274. }
  275. input:focus, textarea:focus { outline: 1px solid var(--muted); }
  276. textarea { min-height: 9rem; resize: vertical; }
  277. button, .btn {
  278. display: inline-block;
  279. margin-top: 1.4rem;
  280. padding: .75rem 1.8rem;
  281. background: var(--fg);
  282. color: var(--bg);
  283. border: none;
  284. font: inherit;
  285. font-size: .8rem;
  286. letter-spacing: .18em;
  287. text-transform: uppercase;
  288. cursor: pointer;
  289. border-radius: 4px;
  290. }
  291. .btn-ghost {
  292. background: none;
  293. color: var(--fg);
  294. border: 1px solid var(--line);
  295. }
  296. .btn-danger { background: var(--danger); color: #fff; }
  297. .flash { padding: .8rem 1.1rem; border-radius: 4px; margin-bottom: 1.5rem; font-size: .9rem; }
  298. .flash-ok { background: rgba(111,191,143,.12); border: 1px solid rgba(111,191,143,.4); color: var(--ok); }
  299. .flash-error { background: rgba(224,91,77,.12); border: 1px solid rgba(224,91,77,.4); color: var(--danger); }
  300. /* --------------------------------------------------------------------------
  301. Admin
  302. -------------------------------------------------------------------------- */
  303. body.admin { background: #101012; }
  304. .admin-nav {
  305. display: flex;
  306. align-items: center;
  307. justify-content: space-between;
  308. flex-wrap: wrap;
  309. gap: .8rem;
  310. padding: 1rem clamp(1rem, 3vw, 2rem);
  311. border-bottom: 1px solid var(--line);
  312. background: var(--bg);
  313. }
  314. .admin-nav .nav-links { flex-wrap: wrap; gap: 1.2rem; }
  315. .admin-main { max-width: 1000px; margin: 0 auto; padding: 2.5rem clamp(1rem, 3vw, 2rem) 5rem; }
  316. .admin-main h1 { font-weight: 400; font-size: 1.5rem; margin-bottom: 1.6rem; }
  317. .admin-main h2 { font-weight: 400; font-size: 1.1rem; margin: 2.2rem 0 1rem; }
  318. .card {
  319. background: var(--bg-raise);
  320. border: 1px solid var(--line);
  321. border-radius: 6px;
  322. padding: 1.5rem;
  323. margin-bottom: 1.5rem;
  324. }
  325. table { width: 100%; border-collapse: collapse; font-size: .92rem; }
  326. th, td { text-align: left; padding: .65rem .5rem; border-bottom: 1px solid var(--line); vertical-align: middle; }
  327. th { color: var(--muted); font-weight: 400; font-size: .75rem; letter-spacing: .12em; text-transform: uppercase; }
  328. .tag { display: inline-block; padding: .1rem .55rem; border-radius: 99px; font-size: .72rem; border: 1px solid var(--line); color: var(--muted); }
  329. .tag-lock { border-color: rgba(111,191,143,.5); color: var(--ok); }
  330. .tag-expired{ border-color: rgba(224,91,77,.5); color: var(--danger); }
  331. .thumb-row { display: flex; flex-wrap: wrap; gap: 10px; }
  332. .thumb-row figure { position: relative; width: 140px; }
  333. .thumb-row img { width: 140px; height: 100px; object-fit: cover; border-radius: 4px; background: #000; }
  334. .thumb-row figcaption { font-size: .7rem; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; margin-top: .25rem; }
  335. .thumb-row form { position: absolute; top: 4px; right: 4px; }
  336. .thumb-row form button { margin: 0; padding: .15rem .5rem; font-size: .7rem; background: rgba(0,0,0,.65); color: #fff; border-radius: 3px; }
  337. /* Upload queue */
  338. .dropzone {
  339. border: 2px dashed var(--line);
  340. border-radius: 6px;
  341. padding: 2.5rem 1.5rem;
  342. text-align: center;
  343. color: var(--muted);
  344. cursor: pointer;
  345. transition: border-color .2s, color .2s;
  346. }
  347. .dropzone.drag { border-color: var(--fg); color: var(--fg); }
  348. .upload-list { margin-top: 1rem; font-size: .85rem; }
  349. .upload-item { display: flex; align-items: center; gap: .8rem; padding: .4rem 0; border-bottom: 1px solid var(--line); }
  350. .upload-item .name { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  351. .upload-item .state { color: var(--muted); min-width: 90px; text-align: right; }
  352. .upload-item .state.done { color: var(--ok); }
  353. .upload-item .state.error { color: var(--danger); }
  354. .upload-item .bar { width: 120px; height: 4px; background: var(--line); border-radius: 2px; overflow: hidden; }
  355. .upload-item .bar i { display: block; height: 100%; width: 0; background: var(--fg); transition: width .2s; }
  356. .help { color: var(--muted); font-size: .85rem; margin-top: .5rem; }
  357. .login-wrap { min-height: 80svh; display: grid; place-items: center; padding: 1.5rem; }
  358. .login-card { width: 100%; max-width: 22rem; }
  359. .login-card h1 { text-align: center; font-weight: 300; letter-spacing: .15em; text-transform: uppercase; font-size: 1.2rem; }