/* News › X (/news?view=x): the Blog | X pill and one plain list of post cards, newest first, at the
   site's reading width. server/x-render.js renders the cards and public/x-feed.js keeps them live with the
   same markup. X's display rules fix each card's anatomy (avatar left of the name and @username, the text
   unaltered, the X mark top-right, the time and Reply/Repost/Like); the site's glass, Inter and tokens give
   the look in both themes. Ropeak's one line, why the post matters, sits above the card, outside it.
   Nothing loops at rest. */

/* Link and action tones, each at least 4.5:1 on the glass in its theme. */
.x-feed {
  --x-amber:#9a5600;
  --x-green:#047a45;
  --x-blue:#0a5cc7;
  --x-like:#c8106a
}

[data-theme=dark] .x-feed {
  --x-amber:#ffb547;
  --x-green:#4fd89a;
  --x-blue:#7cb4ff;
  --x-like:#ff6fae
}

/* The pill: the Games | Groups switch, kept at the right of the News heading at every width (as in the mock). */
.page-heading.ranking-page-heading:has(>.news-switch) {
  flex-direction:row;
  align-items:center;
  justify-content:space-between;
  gap:16px
}

.news-switch {
  flex:none
}

.news-switch a {
  min-width:72px;
  text-align:center
}

/* An inset ring: the default 3px offset ran into the track and the red segment; white reads on the red one. */
.news-switch a:focus-visible {
  outline-offset:-2px
}

.news-switch a[aria-current=page]:focus-visible {
  outline-color:#fff;
  outline-offset:-4px
}

/* One column flush with "News.", as wide as the site's articles: the status banner (only during an incident),
   then the posts. */
.x-feed {
  display:grid;
  grid-template-columns:minmax(0,1fr);
  align-items:start;
  max-width:800px;
  margin:0
}

.x-feed>.x-status {
  margin-bottom:20px
}

/* Roblox's own status page reports a problem (status.io): above the posts. */
.x-status {
  display:flex;
  align-items:flex-start;
  gap:10px;
  margin:0;
  padding:11px 14px;
  border:1px solid color-mix(in srgb,var(--x-amber) 35%,transparent);
  border-radius:var(--radius-row);
  background:color-mix(in srgb,var(--x-amber) 9%,transparent);
  color:var(--text-2);
  font-size:14px;
  line-height:1.5
}

.x-status-dot {
  flex:none;
  width:8px;
  height:8px;
  margin-top:7px;
  border-radius:50%;
  background:var(--x-amber);
  box-shadow:0 0 0 3px color-mix(in srgb,var(--x-amber) 22%,transparent)
}

.x-status strong {
  color:var(--ink);
  font-weight:650
}

.x-status a {
  color:var(--ink);
  font-weight:600;
  white-space:nowrap
}

/* The posts, newest first. */
.x-list {
  display:grid;
  gap:20px;
  margin:0;
  padding:0;
  list-style:none
}

/* One post: why it matters, in one short line, then the X card. */
.x-item {
  display:grid;
  gap:7px;
  min-width:0
}

.x-why {
  margin:0 4px;
  color:var(--ink);
  font-size:14px;
  font-weight:650;
  letter-spacing:-.005em;
  line-height:1.4
}

/* The X card. */
.x-post {
  position:relative;
  isolation:isolate;
  min-width:0;
  padding:14px 16px 6px;
  border:1px solid var(--glass-edge);
  border-radius:var(--radius);
  background:var(--glass-fill);
  box-shadow:var(--glass-highlight),var(--glass-shadow);
  transition:border-color var(--t-fast) var(--ease-out)
}

.x-post:hover {
  border-color:var(--glass-edge-strong)
}

/* On touch screens the space around the author and text opens the post; pointers keep their own links only. */
.x-hit {
  position:absolute;
  inset:0;
  z-index:0;
  border-radius:inherit
}

@media(hover:hover) and (pointer:fine) {
  .x-hit {
    display:none
  }
}

@media(hover:none) {
  .x-head,.x-actions {
    pointer-events:none
  }
  .x-head a,.x-actions a {
    pointer-events:auto
  }
}

.x-head,.x-text,.x-media,.x-actions {
  position:relative;
  z-index:1
}

/* Avatar, then the name over "@username · time" (as X lays it out), then the X mark. */
.x-head {
  display:flex;
  align-items:center;
  gap:12px
}

.x-avatar-link {
  flex:none;
  display:block;
  border-radius:50%
}

.x-avatar {
  flex:none;
  display:block;
  width:48px;
  height:48px;
  border-radius:50%;
  object-fit:cover;
  background:var(--surface-raised);
  outline:1px solid var(--glass-edge);
  outline-offset:-1px
}

/* No picture from X: the author's initial in a plain circle, never Ropeak's own mark. */
.x-avatar-blank {
  display:grid;
  place-items:center;
  color:var(--text-3);
  font-size:15px;
  font-weight:700;
  line-height:1;
  user-select:none
}

.x-names {
  display:flex;
  flex-direction:column;
  min-width:0;
  line-height:1.3
}

.x-author {
  min-width:0;
  overflow:hidden;
  color:inherit;
  text-decoration:none;
  text-overflow:ellipsis;
  white-space:nowrap
}

.x-name {
  color:var(--ink);
  font-size:15px;
  font-weight:700;
  letter-spacing:-.01em
}

.x-author:hover .x-name {
  text-decoration:underline
}

/* Where "@username · time" doesn't fit, the time drops to the next line (the @username is never cut short) and its
   dot, pulled back past the line's start, is clipped away. */
.x-byline {
  display:flex;
  flex-wrap:wrap;
  align-items:baseline;
  column-gap:15px;
  min-width:0;
  clip-path:inset(-6px -4px);
  color:var(--text-3);
  font-size:14px;
  white-space:nowrap
}

.x-handle {
  max-width:100%;
  overflow:hidden;
  color:inherit;
  text-decoration:none;
  text-overflow:ellipsis
}

.x-when {
  display:inline-flex;
  gap:5px;
  margin-inline-start:-10px
}

.x-sep {
  display:inline-block;
  width:5px;
  text-align:center
}

.x-time-link {
  flex:none;
  color:inherit;
  font-variant-numeric:tabular-nums;
  text-decoration:none
}

.x-handle:hover,.x-time-link:hover {
  color:var(--ink);
  text-decoration:underline
}

.x-logo {
  flex:none;
  display:inline-grid;
  place-items:center;
  align-self:flex-start;
  width:34px;
  height:34px;
  margin:-5px -8px 0 auto;
  border-radius:50%;
  color:var(--ink);
  transition:background-color var(--t-fast) var(--ease-out)
}

.x-logo:hover {
  background:var(--row-hover)
}

.x-mark {
  display:block;
  width:18px;
  height:18px
}

/* The text exactly as posted: X's line breaks kept, long links free to wrap. */
.x-text {
  margin:10px 0 0;
  color:var(--ink);
  font-size:15px;
  line-height:1.55;
  white-space:pre-wrap;
  overflow-wrap:anywhere
}

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

.x-text a:hover {
  text-decoration:underline
}

.x-media {
  display:flex;
  align-items:center;
  gap:8px;
  width:fit-content;
  max-width:100%;
  margin-top:10px;
  padding:7px 12px;
  border:1px solid var(--control-edge);
  border-radius:var(--radius-row);
  background:var(--control-fill);
  color:var(--text-2);
  font-size:13px;
  font-weight:600;
  text-decoration:none;
  transition:border-color var(--t-fast) var(--ease-out),color var(--t-fast) var(--ease-out)
}

.x-media .x-icon {
  width:16px;
  height:16px
}

.x-media:hover {
  border-color:var(--control-edge-hover);
  color:var(--ink)
}

/* Reply, Repost and Like as X Web Intents, from the left edge of the text. */
.x-actions {
  display:flex;
  align-items:center;
  justify-content:flex-start;
  gap:2px 8px;
  margin:4px 0 0 -10px
}

.x-action {
  --x-tone:var(--x-blue);
  display:inline-flex;
  align-items:center;
  justify-content:center;
  gap:5px;
  min-width:44px;
  height:40px;
  padding:0 10px;
  border-radius:var(--radius-control);
  color:var(--text-3);
  font-size:13px;
  font-variant-numeric:tabular-nums;
  text-decoration:none;
  transition:color var(--t-fast) var(--ease-out),background-color var(--t-fast) var(--ease-out)
}

@media(pointer:fine) {
  .x-action {
    height:34px
  }
}

.x-repost {
  --x-tone:var(--x-green)
}

.x-like {
  --x-tone:var(--x-like)
}

.x-action:hover {
  background:color-mix(in srgb,var(--x-tone) 10%,transparent);
  color:var(--x-tone)
}

.x-icon {
  flex:none;
  display:block
}

.x-count:empty {
  display:none
}

/* Nothing to list: one plain line. */
.x-empty {
  margin:0;
  padding:40px 24px;
  border:1px solid var(--glass-edge);
  border-radius:var(--radius);
  background:var(--glass-fill);
  box-shadow:var(--glass-highlight),var(--glass-shadow);
  color:var(--text-3);
  font-size:15px;
  line-height:1.6;
  text-align:center
}

/* Client states (public/x-feed.js). */
.x-new-posts {
  position:sticky;
  top:calc(var(--header-offset,8px) + 12px);
  z-index:5;
  justify-self:center;
  align-self:start;
  display:inline-flex;
  margin-bottom:14px;
  align-items:center;
  gap:8px;
  height:38px;
  padding:0 18px;
  border:0;
  border-radius:var(--radius-control);
  background:var(--ink);
  box-shadow:0 12px 26px -12px color-mix(in srgb,var(--ink) 70%,transparent);
  color:var(--bg);
  font:inherit;
  font-size:14px;
  font-weight:650;
  cursor:pointer;
  animation:x-pop var(--t-spring) var(--ease-spring) both;
  transition:transform var(--t-fast) var(--ease-out),background-color var(--t-fast) var(--ease-out)
}

.x-new-posts:hover {
  background:color-mix(in srgb,var(--ink) 84%,var(--bg))
}

/* Where the header steps aside (up to 1050 px), any scroll up brings it back over the top of the page, so the sticky
   button moves below it while it's shown (motion.js sets --header-shown). */
@media(max-width:1050px) {
  .x-new-posts {
    transition:top 380ms var(--ease-out),transform var(--t-fast) var(--ease-out),background-color var(--t-fast) var(--ease-out)
  }
  .site-header[data-motion]:not([data-away])~main .x-new-posts {
    top:calc(var(--header-shown,8px) + 12px)
  }
  .site-header[data-motion]:has(:focus-visible)~main .x-new-posts {
    top:calc(var(--header-shown,8px) + 12px)
  }
}

.x-new-posts:active {
  transform:scale(.97)
}

[data-x-announce] {
  position:absolute;
  width:1px;
  height:1px;
  overflow:hidden;
  clip-path:inset(50%);
  white-space:nowrap
}

.x-item.is-entering {
  animation:x-enter var(--t-spring) var(--ease-spring) both
}

.x-item.is-entering .x-post {
  animation:x-glow 1.6s var(--ease-out) both
}

.x-item.is-leaving {
  animation:x-leave var(--t-fast) var(--ease-out) forwards;
  pointer-events:none
}

@keyframes x-enter {
  from {
    opacity:0;
    transform:translateY(-10px) scale(.985)
  }
}

@keyframes x-glow {
  from {
    border-color:color-mix(in srgb,var(--x-blue) 45%,transparent)
  }
}

@keyframes x-leave {
  to {
    opacity:0;
    transform:scale(.98)
  }
}

@keyframes x-pop {
  from {
    opacity:0;
    transform:translateY(-6px) scale(.96)
  }
}

@keyframes x-fade {
  from {
    opacity:0
  }
}

@keyframes x-fade-out {
  to {
    opacity:0
  }
}

/* Reduced motion: things fade in or out where they are; nothing slides or scales. */
@media(prefers-reduced-motion:reduce) {
  .x-item.is-entering {
    animation:x-fade var(--t-base) linear both
  }
  .x-item.is-entering .x-post {
    animation:none
  }
  .x-item.is-leaving {
    animation:x-fade-out var(--t-fast) linear forwards
  }
  .x-new-posts {
    animation:x-fade var(--t-base) linear both;
    transition:none
  }
  .x-new-posts:active {
    transform:none
  }
  .x-post,.x-logo,.x-media,.x-action,.x-new-posts {
    transition:none
  }
}

/* Phones: the list keeps the page's full width; cards stay airy and the first post shows on the first screen. */
@media(max-width:760px) {
  .news-switch a {
    min-width:60px;
    padding:8px 16px
  }
  .x-list {
    gap:18px
  }
  .x-post {
    padding:14px 14px 6px
  }
  .x-empty {
    padding:32px 20px
  }
}

@media(max-width:380px) {
  .x-post {
    padding:13px 12px 6px
  }
  .x-head {
    gap:10px
  }
  .x-action {
    min-width:40px;
    padding:0 8px
  }
  .x-actions {
    margin-left:-8px
  }
}
