/* GoblinPay checkout + admin styles. One hand-written file, no build step, no JavaScript. Mobile-first (a 390px phone is the primary surface). */ :root { --bg: #14140f; --panel: #1e1e17; --ink: #f4f1e6; --dim: #a8a294; --accent: #e9c542; /* Goblin yellow */ --green: #57b894; --red: #d97070; --line: #33322a; --radius: 14px; } * { box-sizing: border-box; } body { margin: 0; background: var(--bg); color: var(--ink); font: 16px/1.5 system-ui, -apple-system, "Segoe UI", Roboto, sans-serif; -webkit-text-size-adjust: 100%; } main { max-width: 30rem; margin: 0 auto; padding: 1.5rem 1.25rem 3rem; } main.admin { max-width: 60rem; } /* Apple-Pay-style header: the white Goblin Pay lockup, centered with generous whitespace, is the only branding. No separate heading text (the lockup itself reads "Goblin Pay"), keeping the sheet clean and uncluttered. The lockup is the page's h1; its alt carries the heading for assistive tech. */ .brand { margin: 0.25rem 0 1.75rem; text-align: center; line-height: 0; } .brandmark { height: 4rem; width: auto; display: inline-block; } h1 { font-size: 1.5rem; margin: 0 0 0.5rem; } h2 { font-size: 1.05rem; margin: 1.75rem 0 0.5rem; color: var(--dim); text-transform: uppercase; letter-spacing: 0.04em; } .amount { font-size: 2rem; font-weight: 700; color: var(--accent); margin: 0.25rem 0 1rem; } .status { font-weight: 600; margin: 0.5rem 0 1rem; } .status.open { color: var(--dim); } .status.paid, .status-confirmed, .status-replied { color: var(--green); } .status.confirming { color: var(--accent); } .status.expired { color: var(--red); } .status-received { color: var(--accent); } .qr { background: #fff; border-radius: var(--radius); padding: 0.75rem; width: 100%; max-width: 18rem; margin: 0 auto 1rem; } .qr svg { display: block; width: 100%; height: auto; } /* "Open in Goblin" deep-link: the primary tap-to-pay affordance on the device that holds the wallet. Styled as the accent pill (matching the submit button) but centered under the QR. Harmless where the goblin: scheme has no handler. */ .open-wallet { display: block; width: fit-content; margin: 0 auto 0.75rem; background: var(--accent); color: #201d09; text-decoration: none; border-radius: 999px; padding: 0.7rem 1.4rem; font-weight: 700; font-size: 1rem; } .open-wallet:hover { filter: brightness(1.05); } .hint { color: var(--dim); font-size: 0.9rem; } .memo { color: var(--ink); background: var(--panel); padding: 0.5rem 0.75rem; border-radius: 10px; } label { display: block; font-size: 0.85rem; color: var(--dim); margin: 0.75rem 0 0.25rem; } .copybox, textarea { width: 100%; background: var(--panel); color: var(--ink); border: 1px solid var(--line); border-radius: 10px; padding: 0.6rem 0.7rem; font-family: ui-monospace, "SFMono-Regular", Menlo, monospace; font-size: 0.8rem; resize: vertical; word-break: break-all; } /* The invoice slatepack must be fully visible without scrolling, ENDSLATEPACK. included, and its length varies per invoice: auto-fit the box to its content where field-sizing is supported; elsewhere the rows attribute (sized to a measured real invoice at 390px) is the fallback. */ #invoice-slatepack { field-sizing: content; } button { display: block; margin: 0.75rem auto 0; background: var(--accent); color: #201d09; border: 0; border-radius: 999px; padding: 0.7rem 1.4rem; font-weight: 700; font-size: 1rem; cursor: pointer; } button:hover { filter: brightness(1.05); } details.manual { margin-top: 1.5rem; border-top: 1px solid var(--line); padding-top: 0.75rem; } details.manual summary { cursor: pointer; color: var(--accent); font-weight: 600; } details.manual ol { color: var(--dim); font-size: 0.9rem; padding-left: 1.2rem; } /* Each first-class way to pay (Goblin/Nostr, Slatepack/grin1). */ .pay-method { margin-top: 1.5rem; border-top: 1px solid var(--line); padding-top: 0.75rem; } .pay-method:first-of-type { border-top: none; padding-top: 0; } .pay-method ol { color: var(--dim); font-size: 0.9rem; padding-left: 1.2rem; } /* Two-rail switcher (CSS only, no JavaScript): hidden radios drive which panel shows; the tab labels are the control. Radios precede the panels so the general-sibling combinator can target them. The radios and tabs are rendered only when BOTH rails are available (grin1 rail is operator opt-in, default off); a single rail renders its panel directly with no switcher chrome, so panels are visible by default and the radios hide the unselected one. */ .rails { margin-top: 1.25rem; } .rail-radio { position: absolute; width: 0; height: 0; opacity: 0; pointer-events: none; } .rail-tabs { display: flex; gap: 0.4rem; margin-bottom: 1rem; } .rail-tab { flex: 1; text-align: center; cursor: pointer; /* Center the label within the tab: sibling tabs stretch to equal height, so when one label wraps to two lines the single-line label stays vertically centered instead of hugging the top. */ display: flex; align-items: center; justify-content: center; padding: 0.55rem 0.5rem; border: 1px solid var(--line); border-radius: var(--radius); color: var(--dim); font-size: 0.9rem; font-weight: 600; background: var(--panel); } #rail-goblin:checked ~ .rail-tabs [for="rail-goblin"], #rail-grin:checked ~ .rail-tabs [for="rail-grin"] { color: var(--bg); background: var(--accent); border-color: var(--accent); } #rail-goblin:checked ~ #panel-grin, #rail-grin:checked ~ #panel-goblin { display: none; } .grin-sub { margin-top: 1.5rem; border-top: 1px solid var(--line); padding-top: 1rem; } .grin-sub:first-child { margin-top: 0; border-top: none; padding-top: 0; } .grin-sub h3 { margin: 0 0 0.5rem; font-size: 1rem; } a { color: var(--accent); } .footer { margin-top: 2rem; color: var(--dim); font-size: 0.78rem; text-align: center; } /* Admin tables */ table { width: 100%; border-collapse: collapse; font-size: 0.85rem; } th, td { text-align: left; padding: 0.4rem 0.5rem; border-bottom: 1px solid var(--line); } th { color: var(--dim); font-weight: 600; } .mono { font-family: ui-monospace, monospace; font-size: 0.75rem; color: var(--dim); word-break: break-all; } .config ul { list-style: none; padding: 0; } .config li { padding: 0.2rem 0; color: var(--dim); } code { color: var(--ink); background: var(--panel); padding: 0.05rem 0.35rem; border-radius: 6px; }